From 039592ba220fb6266ece77b8ea26cd31f0038432 Mon Sep 17 00:00:00 2001 From: Ewan Bains Date: Tue, 6 Sep 2022 22:44:47 +0100 Subject: [PATCH 01/11] Removing cyclic dependency --- Cargo.lock | 46 + preload-syscallee/Cargo.toml | 42 + .../src/allocation_tracker.rs | 0 {preload => preload-syscallee}/src/api.rs | 0 .../src/arc_lite.rs | 0 {preload => preload-syscallee}/src/arch.rs | 0 {preload => preload-syscallee}/src/channel.rs | 0 {preload => preload-syscallee}/src/event.rs | 0 {preload => preload-syscallee}/src/global.rs | 0 {preload => preload-syscallee}/src/init.rs | 0 preload-syscallee/src/lib.rs | 95 ++ {preload => preload-syscallee}/src/logger.rs | 0 {preload => preload-syscallee}/src/macros.rs | 0 {preload => preload-syscallee}/src/nohash.rs | 0 {preload => preload-syscallee}/src/opt.rs | 0 .../src/ordered_map.rs | 0 .../src/processing_thread.rs | 0 .../src/raw_file.rs | 0 .../src/spin_lock.rs | 0 {preload => preload-syscallee}/src/syscall.rs | 0 .../src/timestamp.rs | 0 {preload => preload-syscallee}/src/unwind.rs | 0 {preload => preload-syscallee}/src/utils.rs | 0 .../src/writer_memory.rs | 0 {preload => preload-syscallee}/src/writers.rs | 0 preload-syscaller/Cargo.toml | 42 + preload-syscaller/src/allocation_tracker.rs | 345 ++++++ preload-syscaller/src/api.rs | 955 +++++++++++++++ preload-syscaller/src/arc_lite.rs | 86 ++ preload-syscaller/src/arch.rs | 7 + preload-syscaller/src/channel.rs | 76 ++ preload-syscaller/src/event.rs | 160 +++ preload-syscaller/src/global.rs | 1024 +++++++++++++++++ preload-syscaller/src/init.rs | 81 ++ preload-syscaller/src/lib.rs | 95 ++ preload-syscaller/src/logger.rs | 239 ++++ preload-syscaller/src/macros.rs | 63 + preload-syscaller/src/nohash.rs | 32 + preload-syscaller/src/opt.rs | 191 +++ preload-syscaller/src/ordered_map.rs | 243 ++++ preload-syscaller/src/processing_thread.rs | 854 ++++++++++++++ preload-syscaller/src/raw_file.rs | 122 ++ preload-syscaller/src/spin_lock.rs | 84 ++ preload-syscaller/src/syscall.rs | 157 +++ preload-syscaller/src/timestamp.rs | 30 + preload-syscaller/src/unwind.rs | 461 ++++++++ preload-syscaller/src/utils.rs | 241 ++++ preload-syscaller/src/writer_memory.rs | 135 +++ preload-syscaller/src/writers.rs | 249 ++++ preload/Cargo.toml | 2 + preload/src/lib.rs | 97 +- 51 files changed, 6159 insertions(+), 95 deletions(-) create mode 100644 preload-syscallee/Cargo.toml rename {preload => preload-syscallee}/src/allocation_tracker.rs (100%) rename {preload => preload-syscallee}/src/api.rs (100%) rename {preload => preload-syscallee}/src/arc_lite.rs (100%) rename {preload => preload-syscallee}/src/arch.rs (100%) rename {preload => preload-syscallee}/src/channel.rs (100%) rename {preload => preload-syscallee}/src/event.rs (100%) rename {preload => preload-syscallee}/src/global.rs (100%) rename {preload => preload-syscallee}/src/init.rs (100%) create mode 100644 preload-syscallee/src/lib.rs rename {preload => preload-syscallee}/src/logger.rs (100%) rename {preload => preload-syscallee}/src/macros.rs (100%) rename {preload => preload-syscallee}/src/nohash.rs (100%) rename {preload => preload-syscallee}/src/opt.rs (100%) rename {preload => preload-syscallee}/src/ordered_map.rs (100%) rename {preload => preload-syscallee}/src/processing_thread.rs (100%) rename {preload => preload-syscallee}/src/raw_file.rs (100%) rename {preload => preload-syscallee}/src/spin_lock.rs (100%) rename {preload => preload-syscallee}/src/syscall.rs (100%) rename {preload => preload-syscallee}/src/timestamp.rs (100%) rename {preload => preload-syscallee}/src/unwind.rs (100%) rename {preload => preload-syscallee}/src/utils.rs (100%) rename {preload => preload-syscallee}/src/writer_memory.rs (100%) rename {preload => preload-syscallee}/src/writers.rs (100%) create mode 100644 preload-syscaller/Cargo.toml create mode 100644 preload-syscaller/src/allocation_tracker.rs create mode 100644 preload-syscaller/src/api.rs create mode 100644 preload-syscaller/src/arc_lite.rs create mode 100644 preload-syscaller/src/arch.rs create mode 100644 preload-syscaller/src/channel.rs create mode 100644 preload-syscaller/src/event.rs create mode 100644 preload-syscaller/src/global.rs create mode 100644 preload-syscaller/src/init.rs create mode 100644 preload-syscaller/src/lib.rs create mode 100644 preload-syscaller/src/logger.rs create mode 100644 preload-syscaller/src/macros.rs create mode 100644 preload-syscaller/src/nohash.rs create mode 100644 preload-syscaller/src/opt.rs create mode 100644 preload-syscaller/src/ordered_map.rs create mode 100644 preload-syscaller/src/processing_thread.rs create mode 100644 preload-syscaller/src/raw_file.rs create mode 100644 preload-syscaller/src/spin_lock.rs create mode 100644 preload-syscaller/src/syscall.rs create mode 100644 preload-syscaller/src/timestamp.rs create mode 100644 preload-syscaller/src/unwind.rs create mode 100644 preload-syscaller/src/utils.rs create mode 100644 preload-syscaller/src/writer_memory.rs create mode 100644 preload-syscaller/src/writers.rs diff --git a/Cargo.lock b/Cargo.lock index b76c370a..8aee53c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,6 +531,8 @@ dependencies = [ "nwind", "parking_lot 0.12.1", "perf_event_open", + "preload-syscallee", + "preload-syscaller", "sc", "smallvec 1.9.0", "thread-local-reentrant", @@ -1817,6 +1819,50 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "preload-syscallee" +version = "0.9.0" +dependencies = [ + "common", + "glob 0.2.11", + "goblin", + "lazy_static", + "libc", + "log", + "lru", + "memmap", + "nwind", + "parking_lot 0.12.1", + "perf_event_open", + "sc", + "smallvec 1.9.0", + "thread-local-reentrant", + "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", + "tikv-jemallocator 0.4.1", +] + +[[package]] +name = "preload-syscaller" +version = "0.9.0" +dependencies = [ + "common", + "glob 0.2.11", + "goblin", + "lazy_static", + "libc", + "log", + "lru", + "memmap", + "nwind", + "parking_lot 0.12.1", + "perf_event_open", + "sc", + "smallvec 1.9.0", + "thread-local-reentrant", + "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", + "tikv-jemallocator 0.4.1", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" diff --git a/preload-syscallee/Cargo.toml b/preload-syscallee/Cargo.toml new file mode 100644 index 00000000..977e0a93 --- /dev/null +++ b/preload-syscallee/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "preload-syscallee" +version = "0.9.0" +authors = ["Jan Bujak "] +edition = "2018" + +[dependencies] +parking_lot = { version = "0.12" } +libc = "0.2" +sc = { version = "0.2", optional = true } +lazy_static = "1" +memmap = "0.7" +log = "0.4" +glob = "0.2" +lru = { version = "0.6", default-features = false } +tikv-jemallocator = { path = "../jemallocator", default-features = false } +tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } +goblin = "0.0.24" +smallvec = { version = "1", features = ["union"] } + +[dependencies.thread-local-reentrant] +git = "https://github.com/koute/not-perf.git" +rev = "18bd8d3" + +[dependencies.nwind] +git = "https://github.com/koute/not-perf.git" +rev = "18bd8d3" +features = ["log", "local-unwinding"] +default-features = false + +[dependencies.perf_event_open] +git = "https://github.com/koute/not-perf.git" +rev = "18bd8d3" + +[dependencies.common] +path = "../common" + +[features] +default = [] +debug-logs = ["nwind/debug-logs", "nwind/addr2line"] +nightly = ["parking_lot/nightly"] +jemalloc = [] diff --git a/preload/src/allocation_tracker.rs b/preload-syscallee/src/allocation_tracker.rs similarity index 100% rename from preload/src/allocation_tracker.rs rename to preload-syscallee/src/allocation_tracker.rs diff --git a/preload/src/api.rs b/preload-syscallee/src/api.rs similarity index 100% rename from preload/src/api.rs rename to preload-syscallee/src/api.rs diff --git a/preload/src/arc_lite.rs b/preload-syscallee/src/arc_lite.rs similarity index 100% rename from preload/src/arc_lite.rs rename to preload-syscallee/src/arc_lite.rs diff --git a/preload/src/arch.rs b/preload-syscallee/src/arch.rs similarity index 100% rename from preload/src/arch.rs rename to preload-syscallee/src/arch.rs diff --git a/preload/src/channel.rs b/preload-syscallee/src/channel.rs similarity index 100% rename from preload/src/channel.rs rename to preload-syscallee/src/channel.rs diff --git a/preload/src/event.rs b/preload-syscallee/src/event.rs similarity index 100% rename from preload/src/event.rs rename to preload-syscallee/src/event.rs diff --git a/preload/src/global.rs b/preload-syscallee/src/global.rs similarity index 100% rename from preload/src/global.rs rename to preload-syscallee/src/global.rs diff --git a/preload/src/init.rs b/preload-syscallee/src/init.rs similarity index 100% rename from preload/src/init.rs rename to preload-syscallee/src/init.rs diff --git a/preload-syscallee/src/lib.rs b/preload-syscallee/src/lib.rs new file mode 100644 index 00000000..6565759b --- /dev/null +++ b/preload-syscallee/src/lib.rs @@ -0,0 +1,95 @@ +#[macro_use] +extern crate log; + +#[macro_use] +extern crate lazy_static; + +#[cfg(feature = "sc")] +#[macro_use] +extern crate sc; + +#[macro_use] +extern crate thread_local_reentrant; + +use std::fs::read_link; + +use std::os::unix::ffi::OsStrExt; + +#[macro_use] +mod macros; +mod unwind; +mod timestamp; +mod spin_lock; +mod channel; +mod utils; +mod arch; +mod logger; +mod opt; +mod syscall; +mod raw_file; +mod arc_lite; +mod writers; +mod writer_memory; +mod api; +mod event; +mod init; +mod processing_thread; +mod global; +mod ordered_map; +mod nohash; +mod allocation_tracker; + +use crate::event::InternalEvent; +use crate::utils::read_file; + +//#[global_allocator] +//static mut ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + +pub(crate) const PAGE_SIZE: usize = 4096; + +lazy_static! { + pub(crate) static ref PID: u32 = { + let pid = crate::syscall::getpid() as u32; + pid + }; + pub(crate) static ref CMDLINE: Vec< u8 > = { + read_file( "/proc/self/cmdline" ).unwrap() + }; + pub(crate) static ref EXECUTABLE: Vec< u8 > = { + let executable: Vec< u8 > = read_link( "/proc/self/exe" ).unwrap().as_os_str().as_bytes().into(); + executable + }; +} + +//pub use crate::api::{ +// memory_profiler_raw_mmap, +// memory_profiler_raw_munmap, +// +// __register_frame, +// __deregister_frame, +// +// _exit, +// _Exit, +// fork, +// +// malloc, +// calloc, +// realloc, +// reallocarray, +// free, +// posix_memalign, +// malloc_usable_size, +// mmap, +// munmap, +// mallopt, +// memalign, +// aligned_alloc, +// valloc, +// pvalloc, +// +// memory_profiler_set_marker, +// memory_profiler_override_next_timestamp, +// memory_profiler_start, +// memory_profiler_stop, +// memory_profiler_sync +//}; diff --git a/preload/src/logger.rs b/preload-syscallee/src/logger.rs similarity index 100% rename from preload/src/logger.rs rename to preload-syscallee/src/logger.rs diff --git a/preload/src/macros.rs b/preload-syscallee/src/macros.rs similarity index 100% rename from preload/src/macros.rs rename to preload-syscallee/src/macros.rs diff --git a/preload/src/nohash.rs b/preload-syscallee/src/nohash.rs similarity index 100% rename from preload/src/nohash.rs rename to preload-syscallee/src/nohash.rs diff --git a/preload/src/opt.rs b/preload-syscallee/src/opt.rs similarity index 100% rename from preload/src/opt.rs rename to preload-syscallee/src/opt.rs diff --git a/preload/src/ordered_map.rs b/preload-syscallee/src/ordered_map.rs similarity index 100% rename from preload/src/ordered_map.rs rename to preload-syscallee/src/ordered_map.rs diff --git a/preload/src/processing_thread.rs b/preload-syscallee/src/processing_thread.rs similarity index 100% rename from preload/src/processing_thread.rs rename to preload-syscallee/src/processing_thread.rs diff --git a/preload/src/raw_file.rs b/preload-syscallee/src/raw_file.rs similarity index 100% rename from preload/src/raw_file.rs rename to preload-syscallee/src/raw_file.rs diff --git a/preload/src/spin_lock.rs b/preload-syscallee/src/spin_lock.rs similarity index 100% rename from preload/src/spin_lock.rs rename to preload-syscallee/src/spin_lock.rs diff --git a/preload/src/syscall.rs b/preload-syscallee/src/syscall.rs similarity index 100% rename from preload/src/syscall.rs rename to preload-syscallee/src/syscall.rs diff --git a/preload/src/timestamp.rs b/preload-syscallee/src/timestamp.rs similarity index 100% rename from preload/src/timestamp.rs rename to preload-syscallee/src/timestamp.rs diff --git a/preload/src/unwind.rs b/preload-syscallee/src/unwind.rs similarity index 100% rename from preload/src/unwind.rs rename to preload-syscallee/src/unwind.rs diff --git a/preload/src/utils.rs b/preload-syscallee/src/utils.rs similarity index 100% rename from preload/src/utils.rs rename to preload-syscallee/src/utils.rs diff --git a/preload/src/writer_memory.rs b/preload-syscallee/src/writer_memory.rs similarity index 100% rename from preload/src/writer_memory.rs rename to preload-syscallee/src/writer_memory.rs diff --git a/preload/src/writers.rs b/preload-syscallee/src/writers.rs similarity index 100% rename from preload/src/writers.rs rename to preload-syscallee/src/writers.rs diff --git a/preload-syscaller/Cargo.toml b/preload-syscaller/Cargo.toml new file mode 100644 index 00000000..e640df66 --- /dev/null +++ b/preload-syscaller/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "preload-syscaller" +version = "0.9.0" +authors = ["Jan Bujak "] +edition = "2018" + +[dependencies] +parking_lot = { version = "0.12" } +libc = "0.2" +sc = { version = "0.2", optional = true } +lazy_static = "1" +memmap = "0.7" +log = "0.4" +glob = "0.2" +lru = { version = "0.6", default-features = false } +tikv-jemallocator = { path = "../jemallocator", default-features = false } +tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } +goblin = "0.0.24" +smallvec = { version = "1", features = ["union"] } + +[dependencies.thread-local-reentrant] +git = "https://github.com/koute/not-perf.git" +rev = "18bd8d3" + +[dependencies.nwind] +git = "https://github.com/koute/not-perf.git" +rev = "18bd8d3" +features = ["log", "local-unwinding"] +default-features = false + +[dependencies.perf_event_open] +git = "https://github.com/koute/not-perf.git" +rev = "18bd8d3" + +[dependencies.common] +path = "../common" + +[features] +default = [] +debug-logs = ["nwind/debug-logs", "nwind/addr2line"] +nightly = ["parking_lot/nightly"] +jemalloc = [] diff --git a/preload-syscaller/src/allocation_tracker.rs b/preload-syscaller/src/allocation_tracker.rs new file mode 100644 index 00000000..a992e314 --- /dev/null +++ b/preload-syscaller/src/allocation_tracker.rs @@ -0,0 +1,345 @@ +use std::num::NonZeroUsize; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::collections::HashMap; + +use parking_lot::{Mutex, RwLock}; + +use common::Timestamp; +use common::event::AllocationId; + +use crate::global::StrongThreadHandle; +use crate::unwind::Backtrace; +use crate::event::{InternalAllocation, InternalAllocationId, InternalEvent}; + +pub struct BufferedAllocation { + pub timestamp: Timestamp, + pub allocation: InternalAllocation, + pub backtrace: Backtrace +} + +pub struct AllocationBucket { + pub id: AllocationId, + pub events: smallvec::SmallVec< [BufferedAllocation; 1] > +} + +impl AllocationBucket { + fn is_long_lived( &self, now: Timestamp ) -> bool { + now.as_usecs() >= self.events[0].timestamp.as_usecs() + crate::opt::get().temporary_allocation_lifetime_threshold * 1000 + } +} + +#[derive(Default)] +struct AllocationTrackerRegistry { + per_thread: HashMap< u64, AllocationTracker, crate::nohash::NoHash >, + global: Mutex< crate::ordered_map::OrderedMap< (u64, u64), AllocationBucket, crate::nohash::NoHash > > +} + +static ENABLED: AtomicBool = AtomicBool::new( false ); + +lazy_static! { + static ref ALLOCATION_TRACKER_REGISTRY: RwLock< AllocationTrackerRegistry > = Default::default(); +} + +#[derive(Default)] +struct AllocationTrackerState { + buckets: crate::ordered_map::OrderedMap< u64, AllocationBucket, crate::nohash::NoHash >, +} + +#[repr(transparent)] +pub struct AllocationTracker( Arc< Mutex< AllocationTrackerState > > ); + +pub fn initialize() { + ENABLED.store( crate::opt::get().cull_temporary_allocations, Ordering::SeqCst ); + let _ = ALLOCATION_TRACKER_REGISTRY.write(); +} + +pub fn on_thread_created( unique_tid: u64 ) -> AllocationTracker { + let tracker = AllocationTracker( Arc::new( Mutex::new( AllocationTrackerState::default() ) ) ); + + ALLOCATION_TRACKER_REGISTRY.write().per_thread.insert( unique_tid, AllocationTracker( tracker.0.clone() ) ); + tracker +} + +pub fn on_thread_destroyed( unique_tid: u64 ) { + let mut registry = ALLOCATION_TRACKER_REGISTRY.write(); + if let Some( local_tracker ) = registry.per_thread.remove( &unique_tid ) { + let timestamp = crate::timestamp::get_timestamp(); + let mut local_tracker = local_tracker.0.lock(); + flush_pending( &mut local_tracker.buckets, timestamp ); + + let mut global_tracker = registry.global.lock(); + flush_pending( &mut global_tracker, timestamp ); + + while let Some( (allocation_id, bucket) ) = local_tracker.buckets.pop_front() { + global_tracker.insert( (unique_tid, allocation_id), bucket ); + } + } +} + +pub fn on_tick() { + let registry = ALLOCATION_TRACKER_REGISTRY.read(); + let timestamp = crate::timestamp::get_timestamp(); + { + let mut global_tracker = registry.global.lock(); + flush_pending( &mut global_tracker, timestamp ); + } + for tracker in registry.per_thread.values() { + let mut local_tracker = tracker.0.lock(); + flush_pending( &mut local_tracker.buckets, timestamp ); + } +} + +pub fn on_exit() { + ENABLED.store( false, Ordering::SeqCst ); + + let mut buckets = Vec::new(); + let mut registry = ALLOCATION_TRACKER_REGISTRY.write(); + for (_, tracker) in std::mem::take( &mut registry.per_thread ) { + let mut tracker = tracker.0.lock(); + while let Some( (_, bucket) ) = tracker.buckets.pop_front() { + buckets.push( bucket ); + } + } + + { + let mut global = registry.global.lock(); + while let Some( (_, bucket) ) = global.pop_front() { + buckets.push( bucket ); + } + } + + info!( "Flushing {} bucket(s) on exit", buckets.len() ); + for bucket in buckets { + crate::event::send_event_throttled( move || { + InternalEvent::AllocationBucket( bucket ) + }); + } +} + +fn flush_pending< K >( + allocations: &mut crate::ordered_map::OrderedMap< K, AllocationBucket, crate::nohash::NoHash >, + timestamp: Timestamp +) where K: Copy + PartialEq + Eq + std::hash::Hash { + let temporary_allocation_pending_threshold = crate::opt::get().temporary_allocation_pending_threshold.unwrap_or( !0 ); + while let Some( key ) = allocations.front_key() { + let should_flush = + allocations.len() > temporary_allocation_pending_threshold || + allocations.get( &key ).unwrap().is_long_lived( timestamp ); + + if should_flush { + let bucket = allocations.remove( &key ).unwrap(); + crate::event::send_event_throttled( move || { + InternalEvent::AllocationBucket( bucket ) + }); + } else { + break; + } + } +} + +pub fn on_allocation( + id: InternalAllocationId, + allocation: InternalAllocation, + backtrace: Backtrace, + thread: StrongThreadHandle +) { + let timestamp = crate::timestamp::get_timestamp(); + let id: AllocationId = id.into(); + debug_assert_eq!( id.thread, thread.unique_tid() ); + + if thread.is_dead() { + let mut zombie_events = thread.zombie_events().lock(); + zombie_events.push( + InternalEvent::Alloc { + id, + timestamp, + allocation, + backtrace, + } + ); + + return; + } else if ENABLED.load( Ordering::Relaxed ) && !id.is_untracked() { + let mut bucket = AllocationBucket { + id, + events: Default::default() + }; + + let address = allocation.address; + bucket.events.push( BufferedAllocation { timestamp, allocation, backtrace } ); + + let mut tracker = thread.allocation_tracker().0.lock(); + if tracker.buckets.insert( id.allocation, bucket ).is_some() { + error!( "Duplicate allocation 0x{:08X} with ID {}; this should never happen", address, id ); + } + + flush_pending( &mut tracker.buckets, timestamp ); + return; + } + + crate::event::send_event_throttled( move || { + InternalEvent::Alloc { + id, + timestamp, + allocation, + backtrace, + } + }); + + std::mem::drop( thread ); +} + +pub fn on_reallocation( + id: InternalAllocationId, + old_address: NonZeroUsize, + allocation: InternalAllocation, + backtrace: Backtrace, + thread: StrongThreadHandle +) { + let timestamp = crate::timestamp::get_timestamp(); + let id: AllocationId = id.into(); + if id.is_invalid() { + // TODO: If we're culling temporary allocations try to find one with the same address and flush it. + error!( "Allocation 0x{:08X} with invalid ID {} was reallocated; this should never happen; you probably have an out-of-bounds write somewhere", old_address, id ); + } if thread.is_dead() { + let mut zombie_events = thread.zombie_events().lock(); + zombie_events.push( + InternalEvent::Realloc { + id, + timestamp, + old_address, + allocation, + backtrace, + } + ); + + return; + } else if !thread.is_dead() && ENABLED.load( Ordering::Relaxed ) && !id.is_untracked() { + fn emit( + bucket: &mut AllocationBucket, + timestamp: Timestamp, + id: AllocationId, + old_address: NonZeroUsize, + allocation: InternalAllocation, + backtrace: Backtrace + ) { + if bucket.events.last().unwrap().allocation.address != old_address { + error!( + "Reallocation with ID {} has old pointer 0x{:016X} while it should have 0x{:016X}; this should never happen", + id, + old_address, + allocation.address + ); + } + + bucket.events.push( BufferedAllocation { timestamp, allocation, backtrace } ); + } + + if id.thread == thread.unique_tid() { + let mut tracker = thread.allocation_tracker().0.lock(); + flush_pending( &mut tracker.buckets, timestamp ); + + if let Some( bucket ) = tracker.buckets.get_mut( &id.allocation ) { + return emit( bucket, timestamp, id, old_address, allocation, backtrace ); + } + } else { + let registry = ALLOCATION_TRACKER_REGISTRY.read(); + if let Some( registry ) = registry.per_thread.get( &id.thread ) { + let mut tracker = registry.0.lock(); + flush_pending( &mut tracker.buckets, timestamp ); + + if let Some( bucket ) = tracker.buckets.get_mut( &id.allocation ) { + return emit( bucket, timestamp, id, old_address, allocation, backtrace ); + } + } else { + let mut buckets = registry.global.lock(); + flush_pending( &mut buckets, timestamp ); + + if let Some( bucket ) = buckets.get_mut( &(id.thread, id.allocation) ) { + return emit( bucket, timestamp, id, old_address, allocation, backtrace ); + } + } + } + } + + crate::event::send_event_throttled( move || { + InternalEvent::Realloc { + id, + timestamp, + old_address, + allocation, + backtrace, + } + }); + + std::mem::drop( thread ); +} + +pub fn on_free( + id: InternalAllocationId, + address: NonZeroUsize, + backtrace: Option< Backtrace >, + thread: StrongThreadHandle +) { + let timestamp = crate::timestamp::get_timestamp(); + let id: AllocationId = id.into(); + if id.is_invalid() { + // TODO: If we're culling temporary allocations try to find one with the same address and flush it. + error!( "Allocation 0x{:08X} with invalid ID {} was freed; this should never happen; you probably have an out-of-bounds write somewhere", address.get(), id ); + } if thread.is_dead() { + let mut zombie_events = thread.zombie_events().lock(); + zombie_events.push( + InternalEvent::Free { + timestamp, + id, + address, + backtrace, + tid: thread.system_tid() + } + ); + + return; + } else if !thread.is_dead() && ENABLED.load( Ordering::Relaxed ) && !id.is_untracked() && !id.is_invalid() { + let bucket = + if id.thread == thread.unique_tid() { + let mut tracker = thread.allocation_tracker().0.lock(); + flush_pending( &mut tracker.buckets, timestamp ); + + tracker.buckets.remove( &id.allocation ) + } else { + let registry = ALLOCATION_TRACKER_REGISTRY.read(); + if let Some( registry ) = registry.per_thread.get( &id.thread ) { + let mut tracker = registry.0.lock(); + flush_pending( &mut tracker.buckets, timestamp ); + + tracker.buckets.remove( &id.allocation ) + } else { + let mut allocations = registry.global.lock(); + flush_pending( &mut allocations, timestamp ); + + allocations.remove( &(id.thread, id.allocation) ) + } + }; + + if let Some( bucket ) = bucket { + if bucket.is_long_lived( timestamp ) { + crate::event::send_event_throttled( move || { + InternalEvent::AllocationBucket( bucket ) + }); + } else { + return; + } + } + } + + crate::event::send_event_throttled( move || { + InternalEvent::Free { + timestamp, + id, + address, + backtrace, + tid: thread.system_tid() + } + }); +} diff --git a/preload-syscaller/src/api.rs b/preload-syscaller/src/api.rs new file mode 100644 index 00000000..bc124375 --- /dev/null +++ b/preload-syscaller/src/api.rs @@ -0,0 +1,955 @@ +use std::mem; +use std::ptr; +use std::num::NonZeroUsize; + +use libc::{ + c_void, + c_int, + size_t, + off_t +}; + +use common::event; +use common::Timestamp; + +use crate::InternalEvent; +use crate::event::{InternalAllocation, InternalAllocationId, send_event, send_event_throttled}; +use crate::global::{StrongThreadHandle, on_exit}; +use crate::opt; +use crate::syscall; +use crate::timestamp::get_timestamp; +use crate::unwind; +use crate::allocation_tracker::{on_allocation, on_reallocation, on_free}; + +extern "C" { + #[link_name = "__libc_malloc"] + fn libc_malloc_real( size: size_t ) -> *mut c_void; + #[link_name = "__libc_calloc"] + fn libc_calloc_real( count: size_t, element_size: size_t ) -> *mut c_void; + #[link_name = "__libc_realloc"] + fn libc_realloc_real( ptr: *mut c_void, size: size_t ) -> *mut c_void; + #[link_name = "__libc_free"] + fn libc_free_real( ptr: *mut c_void ); + #[link_name = "__libc_memalign"] + fn libc_memalign_real( alignment: size_t, size: size_t ) -> *mut c_void; + #[link_name = "__libc_mallopt"] + fn libc_mallopt_real( params: c_int, value: c_int ) -> c_int; +} + +extern "C" { + #[link_name = "_rjem_mp_malloc"] + fn jem_malloc_real( size: size_t ) -> *mut c_void; + #[link_name = "_rjem_mp_mallocx"] + fn jem_mallocx_real( size: size_t, flags: c_int ) -> *mut c_void; + #[link_name = "_rjem_mp_calloc"] + fn jem_calloc_real( count: size_t, element_size: size_t ) -> *mut c_void; + #[link_name = "_rjem_mp_sdallocx"] + fn jem_sdallocx_real( pointer: *mut c_void, _size: size_t, _flags: c_int ); + #[link_name = "_rjem_mp_realloc"] + fn jem_realloc_real( old_pointer: *mut c_void, size: size_t ) -> *mut c_void; + #[link_name = "_rjem_mp_rallocx"] + fn jem_rallocx_real( old_pointer: *mut c_void, size: size_t, _flags: c_int ) -> *mut c_void; + #[link_name = "_rjem_mp_xallocx"] + fn jem_xallocx_real( pointer: *mut c_void, size: size_t, extra: size_t, _flags: c_int ) -> size_t; + #[link_name = "_rjem_mp_nallocx"] + fn jem_nallocx_real( size: size_t, _flags: c_int ) -> size_t; + #[link_name = "_rjem_mp_malloc_usable_size"] + fn jem_malloc_usable_size_real( pointer: *mut c_void ) -> size_t; + #[link_name = "_rjem_mp_mallctlnametomib"] + fn jem_mallctlnametomib_real( name: *const libc::c_char, mibp: *mut size_t, miblenp: *mut size_t ) -> c_int; + #[link_name = "_rjem_mp_mallctlbymib"] + fn jem_mallctlbymib_real( mib: *const size_t, miblen: size_t, oldp: *mut c_void, oldpenp: *mut size_t, newp: *mut c_void, newlen: size_t ) -> c_int; + #[link_name = "_rjem_mp_malloc_stats_print"] + fn jem_malloc_stats_print_real( write_cb: Option< unsafe extern "C" fn( *mut c_void, *const libc::c_char ) >, cbopaque: *mut c_void, opts: *const libc::c_char ); + #[link_name = "_rjem_mp_free"] + fn jem_free_real( ptr: *mut c_void ); + #[link_name = "_rjem_mp_memalign"] + fn jem_memalign_real( alignment: size_t, size: size_t ) -> *mut c_void; +} + +extern "C" { + #[link_name = "__libc_fork"] + fn fork_real() -> libc::pid_t; +} + +pub unsafe extern "C" fn memory_profiler_raw_mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { + syscall::mmap( addr, length, prot, flags, fildes, off ) +} + +pub unsafe extern "C" fn memory_profiler_raw_munmap( addr: *mut c_void, length: size_t ) -> c_int { + syscall::munmap( addr, length ) +} + +pub unsafe extern "C" fn _exit( status: c_int ) { + on_exit(); + syscall::exit( status as u32 ); +} + +#[allow(non_snake_case)] +pub unsafe extern "C" fn _Exit( status: c_int ) { + _exit( status ); +} + +pub unsafe extern "C" fn malloc_usable_size( ptr: *mut c_void ) -> size_t { + if ptr.is_null() { + return 0; + } + + #[cfg(feature = "jemalloc")] + { + _rjem_malloc_usable_size( ptr ) + } + + #[cfg(not(feature = "jemalloc"))] + { + let usable_size = get_allocation_metadata( ptr ).usable_size; + match usable_size.checked_sub( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => panic!( "malloc_usable_size: underflow (pointer=0x{:016X}, usable_size={})", ptr as usize , usable_size ) + } + } +} + +#[derive(Debug)] +struct Metadata { + flags: u32, + preceding_free_space: usize, + usable_size: usize +} + +fn get_allocation_metadata( ptr: *mut c_void ) -> Metadata { + if crate::global::using_unprefixed_jemalloc() { + return Metadata { + flags: 0, + preceding_free_space: 0, + usable_size: unsafe { jem_malloc_usable_size_real( ptr ) } + } + } else { + let raw_chunk_size = unsafe { *(ptr as *mut usize).offset( -1 ) }; + let flags = raw_chunk_size & 0b111; + let chunk_size = raw_chunk_size & !0b111; + + let is_prev_in_use = flags & 1 != 0; + let preceding_free_space = if !is_prev_in_use { + unsafe { *(ptr as *mut usize).offset( -2 ) } + } else { + 0 + }; + + let is_mmapped = flags & 2 != 0; + let usable_size = chunk_size - mem::size_of::< usize >() * if is_mmapped { 2 } else { 1 }; + + Metadata { + flags: flags as u32, + preceding_free_space, + usable_size + } + } +} + +unsafe fn tracking_pointer( pointer: *mut c_void, usable_size: usize ) -> *mut InternalAllocationId { + let tracking_offset = usable_size - mem::size_of::< InternalAllocationId >(); + (pointer as *mut u8).add( tracking_offset ) as *mut InternalAllocationId +} + +enum AllocationKind { + Malloc, + Calloc, + Aligned( size_t ) +} + +#[inline(always)] +unsafe fn allocate( requested_size: usize, kind: AllocationKind ) -> *mut c_void { + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let mut thread = StrongThreadHandle::acquire(); + let pointer = + if !crate::global::using_unprefixed_jemalloc() { + match kind { + AllocationKind::Malloc => { + if opt::get().zero_memory { + libc_calloc_real( effective_size as size_t, 1 ) + } else { + libc_malloc_real( effective_size as size_t ) + } + }, + AllocationKind::Calloc => { + libc_calloc_real( effective_size as size_t, 1 ) + }, + AllocationKind::Aligned( alignment ) => { + libc_memalign_real( alignment, effective_size as size_t ) + } + } + } else { + match kind { + AllocationKind::Malloc => { + if opt::get().zero_memory { + jem_calloc_real( effective_size as size_t, 1 ) + } else { + jem_malloc_real( effective_size as size_t ) + } + }, + AllocationKind::Calloc => { + jem_calloc_real( effective_size as size_t, 1 ) + }, + AllocationKind::Aligned( alignment ) => { + jem_memalign_real( alignment, effective_size as size_t ) + } + } + }; + + if !crate::global::is_actively_running() { + thread = None; + } + + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return pointer + }; + + let mut metadata = get_allocation_metadata( pointer ); + let tracking_pointer = tracking_pointer( pointer, metadata.usable_size ); + + let mut thread = if let Some( thread ) = thread { + thread + } else { + std::ptr::write_unaligned( tracking_pointer, InternalAllocationId::UNTRACKED ); + return pointer; + }; + + let id = thread.on_new_allocation(); + std::ptr::write_unaligned( tracking_pointer, id ); + + let backtrace = unwind::grab( &mut thread ); + + if matches!( kind, AllocationKind::Calloc ) { + metadata.flags |= event::ALLOC_FLAG_CALLOC; + } + + let allocation = InternalAllocation { + address, + size: requested_size as usize, + flags: metadata.flags, + tid: thread.system_tid(), + extra_usable_space: (metadata.usable_size - requested_size) as u32, + preceding_free_space: metadata.preceding_free_space as u64, + }; + + on_allocation( id, allocation, backtrace, thread ); + pointer +} + +pub unsafe extern "C" fn malloc( size: size_t ) -> *mut c_void { + allocate( size, AllocationKind::Malloc ) +} + +pub unsafe extern "C" fn calloc( count: size_t, element_size: size_t ) -> *mut c_void { + let size = match count.checked_mul( element_size ) { + None => return ptr::null_mut(), + Some( size ) => size + }; + + allocate( size, AllocationKind::Calloc ) +} + +#[inline(always)] +unsafe fn realloc_impl( old_pointer: *mut c_void, requested_size: size_t ) -> *mut c_void { + let old_address = match NonZeroUsize::new( old_pointer as usize ) { + Some( old_address ) => old_address, + None => return malloc( requested_size ) + }; + + if requested_size == 0 { + free( old_pointer ); + return ptr::null_mut(); + } + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let old_metadata = get_allocation_metadata( old_pointer ); + let old_tracking_pointer = tracking_pointer( old_pointer, old_metadata.usable_size ); + let id = std::ptr::read_unaligned( old_tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + let new_pointer = if !crate::global::using_unprefixed_jemalloc() { + libc_realloc_real( old_pointer, effective_size ) + } else { + jem_realloc_real( old_pointer, effective_size ) + }; + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + if new_pointer.is_null() { + return ptr::null_mut(); + } else { + let new_metadata = get_allocation_metadata( new_pointer ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_metadata.usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); + + return new_pointer; + } + }; + + let backtrace = unwind::grab( &mut thread ); + + if let Some( new_address ) = NonZeroUsize::new( new_pointer as usize ) { + let new_metadata = get_allocation_metadata( new_pointer ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_metadata.usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, id ); + + let allocation = InternalAllocation { + address: new_address, + size: requested_size as usize, + flags: new_metadata.flags, + tid: thread.system_tid(), + extra_usable_space: (new_metadata.usable_size - requested_size) as u32, + preceding_free_space: new_metadata.preceding_free_space as u64, + }; + + on_reallocation( id, old_address, allocation, backtrace, thread ); + new_pointer + } else { + on_free( id, old_address, Some( backtrace ), thread ); + ptr::null_mut() + } +} + +pub unsafe extern "C" fn realloc( old_ptr: *mut c_void, size: size_t ) -> *mut c_void { + realloc_impl( old_ptr, size ) +} + +pub unsafe extern "C" fn reallocarray( old_ptr: *mut c_void, count: size_t, element_size: size_t ) -> *mut c_void { + let size = match (count as usize).checked_mul( element_size as usize ) { + None => { + *libc::__errno_location() = libc::ENOMEM; + return ptr::null_mut() + }, + Some( size ) => size as size_t + }; + + realloc_impl( old_ptr, size ) +} + +pub unsafe extern "C" fn free( pointer: *mut c_void ) { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return + }; + + let metadata = get_allocation_metadata( pointer ); + let tracking_pointer = tracking_pointer( pointer, metadata.usable_size ); + let id = std::ptr::read_unaligned( tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + if !crate::global::using_unprefixed_jemalloc() { + libc_free_real( pointer ); + } else { + jem_free_real( pointer ); + } + + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { thread } else { return }; + let backtrace = if opt::get().grab_backtraces_on_free { + Some( unwind::grab( &mut thread ) ) + } else { + None + }; + + on_free( id, address, backtrace, thread ); +} + +pub unsafe extern "C" fn _rjem_malloc( requested_size: size_t ) -> *mut c_void { + jemalloc_allocate( requested_size, JeAllocationKind::Malloc ) +} + +enum JeAllocationKind { + Malloc, + MallocX( c_int ), + Calloc, + Aligned( size_t ) +} + +fn translate_jemalloc_flags( flags: c_int ) -> u32 { + const MALLOCX_ZERO: c_int = 0x40; + + let mut internal_flags = event::ALLOC_FLAG_JEMALLOC; + if flags & MALLOCX_ZERO != 0 { + internal_flags |= event::ALLOC_FLAG_CALLOC; + } + + internal_flags +} + +unsafe fn jemalloc_allocate( requested_size: usize, kind: JeAllocationKind ) -> *mut c_void { + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let mut thread = StrongThreadHandle::acquire(); + let (pointer, flags) = match kind { + JeAllocationKind::Malloc => (jem_malloc_real( effective_size ), event::ALLOC_FLAG_JEMALLOC), + JeAllocationKind::MallocX( flags ) => (jem_mallocx_real( effective_size, flags ), translate_jemalloc_flags( flags )), + JeAllocationKind::Calloc => (jem_calloc_real( 1, effective_size ), event::ALLOC_FLAG_JEMALLOC | event::ALLOC_FLAG_CALLOC), + JeAllocationKind::Aligned( alignment ) => (jem_memalign_real( alignment, effective_size as size_t ), event::ALLOC_FLAG_JEMALLOC), + }; + + if !crate::global::is_actively_running() { + thread = None; + } + + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return pointer + }; + + let usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( usable_size >= effective_size ); + let tracking_pointer = tracking_pointer( pointer, usable_size ); + + let mut thread = if let Some( thread ) = thread { + thread + } else { + std::ptr::write_unaligned( tracking_pointer, InternalAllocationId::UNTRACKED ); + return pointer; + }; + + let id = thread.on_new_allocation(); + std::ptr::write_unaligned( tracking_pointer, id ); + + let backtrace = unwind::grab( &mut thread ); + let allocation = InternalAllocation { + address, + size: requested_size as usize, + flags, + tid: thread.system_tid(), + extra_usable_space: 0, + preceding_free_space: 0 + }; + + on_allocation( id, allocation, backtrace, thread ); + pointer +} + +pub unsafe extern "C" fn _rjem_mallocx( requested_size: size_t, flags: c_int ) -> *mut c_void { + jemalloc_allocate( requested_size, JeAllocationKind::MallocX( flags ) ) +} + +pub unsafe extern "C" fn _rjem_calloc( count: size_t, element_size: size_t ) -> *mut c_void { + let requested_size = match count.checked_mul( element_size ) { + None => return ptr::null_mut(), + Some( size ) => size + }; + + jemalloc_allocate( requested_size, JeAllocationKind::Calloc ) +} + +pub unsafe extern "C" fn _rjem_sdallocx( pointer: *mut c_void, requested_size: size_t, flags: c_int ) { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return + }; + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return + }; + + let usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( usable_size >= effective_size, "tried to deallocate an allocation without space for the tracking pointer: 0x{:X}", pointer as usize ); + let tracking_pointer = tracking_pointer( pointer, usable_size ); + let id = std::ptr::read_unaligned( tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + jem_sdallocx_real( pointer, effective_size, flags ); + + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { thread } else { return }; + let backtrace = + if opt::get().grab_backtraces_on_free { + Some( unwind::grab( &mut thread ) ) + } else { + None + }; + + on_free( id, address, backtrace, thread ); +} + +pub unsafe extern "C" fn _rjem_realloc( old_pointer: *mut c_void, requested_size: size_t ) -> *mut c_void { + jemalloc_reallocate( old_pointer, requested_size, None ) +} + +pub unsafe extern "C" fn _rjem_rallocx( old_pointer: *mut c_void, requested_size: size_t, flags: c_int ) -> *mut c_void { + jemalloc_reallocate( old_pointer, requested_size, Some( flags ) ) +} + +unsafe fn jemalloc_reallocate( old_pointer: *mut c_void, requested_size: size_t, flags: Option< c_int > ) -> *mut c_void { + let old_address = match NonZeroUsize::new( old_pointer as usize ) { + Some( old_address ) => old_address, + None => return + if let Some( flags ) = flags { + _rjem_mallocx( requested_size, flags ) + } else { + _rjem_malloc( requested_size ) + } + }; + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let old_usable_size = jem_malloc_usable_size_real( old_pointer ); + let old_tracking_pointer = tracking_pointer( old_pointer, old_usable_size ); + let id = std::ptr::read_unaligned( old_tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + let (new_pointer, flags) = if let Some( flags ) = flags { + (jem_rallocx_real( old_pointer, effective_size, flags ), translate_jemalloc_flags( flags )) + } else { + (jem_realloc_real( old_pointer, effective_size ), translate_jemalloc_flags( 0 )) + }; + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + if new_pointer.is_null() { + return ptr::null_mut(); + } else { + let new_usable_size = jem_malloc_usable_size_real( new_pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); + + return new_pointer; + } + }; + + let backtrace = unwind::grab( &mut thread ); + + if let Some( new_address ) = NonZeroUsize::new( new_pointer as usize ) { + let new_usable_size = jem_malloc_usable_size_real( new_pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, id ); + + let allocation = InternalAllocation { + address: new_address, + size: requested_size as usize, + flags, + tid: thread.system_tid(), + extra_usable_space: 0, + preceding_free_space: 0 + }; + + on_reallocation( id, old_address, allocation, backtrace, thread ); + new_pointer + } else { + on_free( id, old_address, Some( backtrace ), thread ); + ptr::null_mut() + } +} + +pub unsafe extern "C" fn _rjem_xallocx( pointer: *mut c_void, requested_size: size_t, extra: size_t, flags: c_int ) -> size_t { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return 0 + }; + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return _rjem_malloc_usable_size( pointer ) + }; + + let old_usable_size = jem_malloc_usable_size_real( pointer ); + let old_tracking_pointer = tracking_pointer( pointer, old_usable_size ); + let id = std::ptr::read_unaligned( old_tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + let new_effective_size = jem_xallocx_real( pointer, effective_size, extra, flags ); + let new_requested_size = new_effective_size.checked_sub( mem::size_of::< InternalAllocationId >() ).expect( "_rjem_xallocx: underflow" ); + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + let new_usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); + + return new_requested_size; + }; + + let backtrace = unwind::grab( &mut thread ); + + let new_usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, id ); + + let allocation = InternalAllocation { + address: address, + size: new_requested_size as usize, + flags: translate_jemalloc_flags( flags ), + tid: thread.system_tid(), + extra_usable_space: 0, + preceding_free_space: 0 + }; + + on_reallocation( id, address, allocation, backtrace, thread ); + new_requested_size +} + +pub unsafe extern "C" fn _rjem_nallocx( requested_size: size_t, flags: c_int ) -> size_t { + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return 0 + }; + + jem_nallocx_real( effective_size, flags ).checked_sub( mem::size_of::< InternalAllocationId >() ).expect( "_rjem_nallocx: underflow" ) +} + +pub unsafe extern "C" fn _rjem_malloc_usable_size( pointer: *mut c_void ) -> size_t { + let usable_size = jem_malloc_usable_size_real( pointer ); + match usable_size.checked_sub( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => { + debug_assert!( std::ptr::read_unaligned( tracking_pointer( pointer, usable_size ) ).is_valid() ); + size + }, + None => panic!( "_rjem_malloc_usable_size: underflow (pointer=0x{:016X}, usable_size={})", pointer as usize , usable_size ) + } +} + +pub unsafe extern "C" fn _rjem_mallctl( name: *const libc::c_char, _oldp: *mut c_void, _oldlenp: *mut size_t, _newp: *mut c_void, _newlen: size_t ) -> c_int { + warn!( "unimplemented: rjem_mallctl called: name={:?}", std::ffi::CStr::from_ptr( name ) ); + + 0 +} + +pub unsafe extern "C" fn _rjem_posix_memalign( memptr: *mut *mut c_void, alignment: size_t, requested_size: size_t ) -> c_int { + if memptr.is_null() { + return libc::EINVAL; + } + + let ptr_size = mem::size_of::< *const c_void >(); + if alignment % ptr_size != 0 || !(alignment / ptr_size).is_power_of_two() || alignment == 0 { + return libc::EINVAL; + } + + let pointer = jemalloc_allocate( requested_size, JeAllocationKind::Aligned( alignment ) ); + *memptr = pointer; + + if pointer.is_null() { + libc::ENOMEM + } else { + 0 + } +} + +pub unsafe extern "C" fn _rjem_aligned_alloc( _alignment: size_t, _size: size_t ) -> *mut c_void { + todo!( "_rjem_aligned_alloc" ); +} + +pub unsafe extern "C" fn _rjem_memalign( _alignment: size_t, _size: size_t ) -> *mut c_void { + todo!( "_rjem_memalign" ); +} + +pub unsafe extern "C" fn _rjem_valloc( _alignment: size_t, _size: size_t ) -> *mut c_void { + todo!( "_rjem_valloc" ); +} + +pub unsafe extern "C" fn _rjem_free( pointer: *mut c_void ) { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return + }; + + let usable_size = jem_malloc_usable_size_real( pointer ); + let tracking_pointer = tracking_pointer( pointer, usable_size ); + let id = std::ptr::read_unaligned( tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + jem_free_real( pointer ); + + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { thread } else { return }; + let backtrace = if opt::get().grab_backtraces_on_free { + Some( unwind::grab( &mut thread ) ) + } else { + None + }; + + on_free( id, address, backtrace, thread ); +} + +pub unsafe extern "C" fn _rjem_sallocx( _pointer: *const c_void, _flags: c_int ) -> size_t { + todo!( "_rjem_sallocx" ); +} + +pub unsafe extern "C" fn _rjem_dallocx( _pointer: *mut c_void, _flags: c_int ) { + todo!( "_rjem_dallocx" ); +} + +pub unsafe extern "C" fn _rjem_mallctlnametomib( name: *const libc::c_char, mibp: *mut size_t, miblenp: *mut size_t ) -> c_int { + jem_mallctlnametomib_real( name, mibp, miblenp ) +} + +pub unsafe extern "C" fn _rjem_mallctlbymib( + mib: *const size_t, + miblen: size_t, + oldp: *mut c_void, + oldpenp: *mut size_t, + newp: *mut c_void, + newlen: size_t, +) -> c_int { + jem_mallctlbymib_real( mib, miblen, oldp, oldpenp, newp, newlen ) +} + +pub unsafe extern "C" fn _rjem_malloc_stats_print( + write_cb: Option< unsafe extern "C" fn( *mut c_void, *const libc::c_char ) >, + cbopaque: *mut c_void, + opts: *const libc::c_char, +) { + jem_malloc_stats_print_real( write_cb, cbopaque, opts ) +} + +pub unsafe extern "C" fn posix_memalign( memptr: *mut *mut c_void, alignment: size_t, requested_size: size_t ) -> c_int { + if memptr.is_null() { + return libc::EINVAL; + } + + let ptr_size = mem::size_of::< *const c_void >(); + if alignment % ptr_size != 0 || !(alignment / ptr_size).is_power_of_two() || alignment == 0 { + return libc::EINVAL; + } + + let pointer = allocate( requested_size, AllocationKind::Aligned( alignment ) ); + *memptr = pointer; + + if pointer.is_null() { + libc::ENOMEM + } else { + 0 + } +} + +pub unsafe extern "C" fn mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { + let mut thread = StrongThreadHandle::acquire(); + if !opt::get().gather_mmap_calls { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + return syscall::mmap( addr, length, prot, flags, fildes, off ); + }; + + let backtrace = unwind::grab( &mut thread ); + + let _lock = crate::global::MMAP_LOCK.lock(); + let ptr = syscall::mmap( addr, length, prot, flags, fildes, off ); + + let timestamp = get_timestamp(); + send_event_throttled( || InternalEvent::Mmap { + pointer: ptr as usize, + length: length as usize, + requested_address: addr as usize, + mmap_protection: prot as u32, + mmap_flags: flags as u32, + file_descriptor: fildes as u32, + offset: off as u64, + backtrace, + timestamp, + thread: thread.decay() + }); + + ptr +} + +pub unsafe extern "C" fn munmap( ptr: *mut c_void, length: size_t ) -> c_int { + let mut thread = StrongThreadHandle::acquire(); + if !opt::get().gather_mmap_calls { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + return syscall::munmap( ptr, length ); + }; + + let backtrace = unwind::grab( &mut thread ); + + let _lock = crate::global::MMAP_LOCK.lock(); + let result = syscall::munmap( ptr, length ); + + let timestamp = get_timestamp(); + send_event_throttled( || InternalEvent::Munmap { + ptr: ptr as usize, + len: length as usize, + backtrace, + timestamp, + thread: thread.decay() + }); + + result +} + +pub unsafe extern "C" fn mallopt( param: c_int, value: c_int ) -> c_int { + if crate::global::using_unprefixed_jemalloc() { + return 0; + } + + let thread = StrongThreadHandle::acquire(); + let result = libc_mallopt_real( param, value ); + + let mut thread = if let Some( thread ) = thread { thread } else { return result }; + let backtrace = unwind::grab( &mut thread ); + + let timestamp = get_timestamp(); + send_event_throttled( || InternalEvent::Mallopt { + param: param as i32, + value: value as i32, + result: result as i32, + backtrace, + timestamp, + thread: thread.decay() + }); + + result +} + +pub unsafe extern "C" fn fork() -> libc::pid_t { + let pid = fork_real(); + if pid == 0 { + crate::global::on_fork(); + } else { + info!( "Fork called; child PID: {}", pid ); + } + + pid +} + +pub unsafe extern "C" fn memalign( _alignment: size_t, _size: size_t ) -> *mut c_void { + unimplemented!( "'memalign' is unimplemented!" ); +} + +pub unsafe extern "C" fn aligned_alloc( _alignment: size_t, _size: size_t ) -> *mut c_void { + unimplemented!( "'aligned_alloc' is unimplemented!" ); +} + +pub unsafe extern "C" fn valloc( _size: size_t ) -> *mut c_void { + unimplemented!( "'valloc' is unimplemented!" ); +} + +pub unsafe extern "C" fn pvalloc( _size: size_t ) -> *mut c_void { + unimplemented!( "'pvalloc' is unimplemented!" ); +} + +pub unsafe extern "C" fn memory_profiler_set_marker( value: u32 ) { + let thread = StrongThreadHandle::acquire(); + send_event( InternalEvent::SetMarker { + value + }); + + mem::drop( thread ); +} + +pub unsafe extern "C" fn memory_profiler_override_next_timestamp( timestamp: u64 ) { + let thread = StrongThreadHandle::acquire(); + send_event_throttled( || InternalEvent::OverrideNextTimestamp { + timestamp: Timestamp::from_usecs( timestamp ) + }); + + mem::drop( thread ); +} + +fn sync() { + let thread = StrongThreadHandle::acquire(); + crate::event::flush(); + crate::global::sync(); + mem::drop( thread ); +} + +pub unsafe extern "C" fn memory_profiler_start() { + debug!( "Start called..." ); + if crate::global::enable() { + sync(); + } + debug!( "Start finished" ); +} + +pub unsafe extern "C" fn memory_profiler_stop() { + debug!( "Stop called..." ); + if crate::global::disable() { + sync(); + } + debug!( "Stop finished" ); +} + +pub unsafe extern "C" fn memory_profiler_sync() { + debug!( "Sync called..." ); + sync(); + debug!( "Sync finished" ); +} + +pub unsafe extern "C" fn __register_frame( fde: *const u8 ) { + debug!( "Registering new frame: 0x{:016X}", fde as usize ); + + if let Some( original ) = crate::global::SYM_REGISTER_FRAME { + original( fde ) + } else { + error!( "__register_frame call ignored since we couldn't find the original symbol" ); + } + + let thread = StrongThreadHandle::acquire(); + unwind::register_frame_by_pointer( fde ); + std::mem::drop( thread ); +} + +pub unsafe extern "C" fn __deregister_frame( fde: *const u8 ) { + debug!( "Deregistering new frame: 0x{:016X}", fde as usize ); + + if let Some( original ) = crate::global::SYM_DEREGISTER_FRAME { + original( fde ) + } else { + error!( "__deregister_frame call ignored since we couldn't find the original symbol" ); + } + + let thread = StrongThreadHandle::acquire(); + unwind::deregister_frame_by_pointer( fde ); + std::mem::drop( thread ); +} + diff --git a/preload-syscaller/src/arc_lite.rs b/preload-syscaller/src/arc_lite.rs new file mode 100644 index 00000000..29ede150 --- /dev/null +++ b/preload-syscaller/src/arc_lite.rs @@ -0,0 +1,86 @@ +use std::ptr::NonNull; +use std::sync::atomic::{self, AtomicUsize, Ordering}; +use std::mem; +use std::ops::Deref; + +struct Inner< T > { + counter: AtomicUsize, + value: T +} + +pub struct ArcLite< T >( NonNull< Inner< T > > ); +unsafe impl< T > Send for ArcLite< T > where T: Sync + Send {} +unsafe impl< T > Sync for ArcLite< T > where T: Sync + Send {} + +impl< T > ArcLite< T > { + pub fn new( value: T ) -> Self { + let ptr = Box::into_raw( Box::new( Inner { + counter: AtomicUsize::new( 1 ), + value + })); + + unsafe { + ArcLite( NonNull::new_unchecked( ptr ) ) + } + } + + pub fn ptr_eq( lhs: &Self, rhs: &Self ) -> bool { + lhs.0 == rhs.0 + } + + #[inline] + unsafe fn counter( arc: &Self ) -> &AtomicUsize { + &arc.0.as_ref().counter + } + + #[inline] + pub fn get_refcount_relaxed( arc: &Self ) -> usize { + unsafe { + Self::counter( arc ).load( Ordering::Relaxed ) + } + } + + #[inline(never)] + unsafe fn drop_slow( arc: &mut Self ) { + mem::drop( Box::from_raw( arc.0.as_ptr() ) ); + } + + pub unsafe fn add( arc: &Self, value: usize ) { + Self::counter( arc ).fetch_add( value, Ordering::SeqCst ); + } + + pub unsafe fn sub( arc: &Self, value: usize ) { + Self::counter( arc ).fetch_sub( value, Ordering::SeqCst ); + } +} + +impl< T > Deref for ArcLite< T > { + type Target = T; + fn deref( &self ) -> &Self::Target { + &unsafe { self.0.as_ref() }.value + } +} + +impl< T > Clone for ArcLite< T > { + #[inline] + fn clone( &self ) -> Self { + unsafe { + ArcLite::counter( self ).fetch_add( 1, Ordering::Relaxed ); + } + ArcLite( self.0 ) + } +} + +impl< T > Drop for ArcLite< T > { + #[inline] + fn drop( &mut self ) { + unsafe { + if ArcLite::counter( self ).fetch_sub( 1, Ordering::Release ) != 1 { + return; + } + + atomic::fence( Ordering::Acquire ); + ArcLite::drop_slow( self ); + } + } +} diff --git a/preload-syscaller/src/arch.rs b/preload-syscaller/src/arch.rs new file mode 100644 index 00000000..b0517534 --- /dev/null +++ b/preload-syscaller/src/arch.rs @@ -0,0 +1,7 @@ +pub const TARGET_ARCH: &str = std::env::consts::ARCH; + +#[cfg(target_endian = "little")] +pub const IS_LITTLE_ENDIAN: bool = true; + +#[cfg(target_endian = "big")] +pub const IS_LITTLE_ENDIAN: bool = false; diff --git a/preload-syscaller/src/channel.rs b/preload-syscaller/src/channel.rs new file mode 100644 index 00000000..693c5980 --- /dev/null +++ b/preload-syscaller/src/channel.rs @@ -0,0 +1,76 @@ +use std::time::Duration; +use std::mem; + +use parking_lot::{ + Mutex, + Condvar +}; + +pub struct Channel< T > { + queue: Mutex< Vec< T > >, + condvar: Condvar +} + +impl< T > Channel< T > { + pub const fn new() -> Self { + Channel { + queue: parking_lot::const_mutex( Vec::new() ), + condvar: Condvar::new() + } + } + + #[allow(dead_code)] + pub fn recv_all( &self, output: &mut Vec< T > ) { + output.clear(); + let mut guard = self.queue.lock(); + if guard.is_empty() { + self.condvar.wait( &mut guard ); + } + + mem::swap( &mut *guard, output ); + } + + pub fn timed_recv_all( &self, output: &mut Vec< T >, duration: Duration ) { + output.clear(); + + let mut guard = self.queue.lock(); + if guard.is_empty() { + self.condvar.wait_for( &mut guard, duration ); + } + + mem::swap( &mut *guard, output ); + } + + pub fn send( &self, value: T ) -> usize { + self.send_with( || value ) + } + + pub fn send_with< F: FnOnce() -> T >( &self, callback: F ) -> usize { + let mut guard = self.queue.lock(); + self.condvar.notify_all(); + guard.reserve( 1 ); + guard.push( callback() ); + guard.len() + } + + pub fn chunked_send_with< F: FnOnce() -> T >( &self, chunk_size: usize, callback: F ) -> usize { + let mut guard = self.queue.lock(); + let length = guard.len() + 1; + if length % chunk_size == 0 { + self.condvar.notify_all(); + } + + guard.reserve( 1 ); + guard.push( callback() ); + length + } + + pub fn flush( &self ) { + self.condvar.notify_all(); + } + + #[allow(dead_code)] + pub fn len( &self ) -> usize { + self.queue.lock().len() + } +} diff --git a/preload-syscaller/src/event.rs b/preload-syscaller/src/event.rs new file mode 100644 index 00000000..a0e1223c --- /dev/null +++ b/preload-syscaller/src/event.rs @@ -0,0 +1,160 @@ +use std::time::Duration; +use std::sync::Arc; +use std::num::NonZeroUsize; + +use common::Timestamp; +use common::event::AllocationId; + +use crate::channel::Channel; +use crate::global::WeakThreadHandle; +use crate::unwind::Backtrace; + +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct InternalAllocationId { + pub thread: u64, + pub allocation: u64, + pub checksum: u64 +} + +impl std::fmt::Display for InternalAllocationId { + fn fmt( &self, fmt: &mut std::fmt::Formatter ) -> std::fmt::Result { + if self.is_valid() { + write!( fmt, "{{{}, {}}}", self.thread, self.allocation ) + } else { + write!( fmt, "{{0x{:X}, 0x{:X}, 0x{:X}}}", self.thread, self.allocation, self.checksum ) + } + } +} + +// These are just arbitrarily picked to be big and random enough. +const UNTRACKED_THREAD: u64 = 0xEAD1F4ED4A816337; +const UNTRACKED_ALLOCATION: u64 = 0xEBBDDB5F42D04E74; + +const CHECKSUM_CONSTANT: u64 = 0x8000000000000000; + +impl InternalAllocationId { + pub const UNTRACKED: Self = Self::new( UNTRACKED_THREAD, UNTRACKED_ALLOCATION ); + + pub const fn new( thread: u64, allocation: u64 ) -> Self { + InternalAllocationId { + thread, + allocation, + checksum: thread ^ allocation ^ CHECKSUM_CONSTANT + } + } + + pub fn is_untracked( self ) -> bool { + self == Self::UNTRACKED + } + + pub fn is_valid( self ) -> bool { + self.thread ^ self.allocation ^ CHECKSUM_CONSTANT == self.checksum + } +} + +impl From< InternalAllocationId > for common::event::AllocationId { + fn from( id: InternalAllocationId ) -> Self { + if id.is_untracked() { + common::event::AllocationId::UNTRACKED + } else if !id.is_valid() { + common::event::AllocationId::INVALID + } else { + common::event::AllocationId { + thread: id.thread, + allocation: id.allocation + } + } + } +} + +pub struct InternalAllocation { + pub address: NonZeroUsize, + pub size: usize, + pub flags: u32, + pub tid: u32, + pub extra_usable_space: u32, + pub preceding_free_space: u64, +} + +pub(crate) enum InternalEvent { + Alloc { + id: AllocationId, + timestamp: Timestamp, + allocation: InternalAllocation, + backtrace: Backtrace, + }, + Realloc { + id: AllocationId, + timestamp: Timestamp, + old_address: NonZeroUsize, + allocation: InternalAllocation, + backtrace: Backtrace, + }, + Free { + id: AllocationId, + timestamp: Timestamp, + address: NonZeroUsize, + backtrace: Option< Backtrace >, + tid: u32 + }, + Exit, + GrabMemoryDump, + SetMarker { + value: u32 + }, + Mmap { + pointer: usize, + requested_address: usize, + length: usize, + mmap_protection: u32, + mmap_flags: u32, + offset: u64, + backtrace: Backtrace, + file_descriptor: u32, + timestamp: Timestamp, + thread: WeakThreadHandle + }, + Munmap { + ptr: usize, + len: usize, + backtrace: Backtrace, + timestamp: Timestamp, + thread: WeakThreadHandle + }, + Mallopt { + param: i32, + value: i32, + result: i32, + backtrace: Backtrace, + timestamp: Timestamp, + thread: WeakThreadHandle + }, + OverrideNextTimestamp { + timestamp: Timestamp + }, + AddressSpaceUpdated { + maps: String, + new_binaries: Vec< Arc< nwind::BinaryData > > + }, + AllocationBucket( crate::allocation_tracker::AllocationBucket ), +} + +static EVENT_CHANNEL: Channel< InternalEvent > = Channel::new(); + +pub(crate) fn send_event( event: InternalEvent ) { + EVENT_CHANNEL.send( event ); +} + +#[inline(always)] +pub(crate) fn send_event_throttled< F: FnOnce() -> InternalEvent >( callback: F ) { + EVENT_CHANNEL.chunked_send_with( 64, callback ); +} + +pub(crate) fn timed_recv_all_events( output: &mut Vec< InternalEvent >, duration: Duration ) { + EVENT_CHANNEL.timed_recv_all( output, duration ) +} + +pub(crate) fn flush() { + EVENT_CHANNEL.flush(); +} diff --git a/preload-syscaller/src/global.rs b/preload-syscaller/src/global.rs new file mode 100644 index 00000000..51806caa --- /dev/null +++ b/preload-syscaller/src/global.rs @@ -0,0 +1,1024 @@ +use std::cell::UnsafeCell; +use std::collections::HashMap; +use std::ops::Deref; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::thread; + +use crate::arc_lite::ArcLite; +use crate::event::{InternalAllocationId, InternalEvent, send_event}; +use crate::spin_lock::{SpinLock, SpinLockGuard}; +use crate::{opt, syscall}; +use crate::unwind::{ThreadUnwindState, prepare_to_start_unwinding}; +use crate::timestamp::Timestamp; +use crate::allocation_tracker::AllocationTracker; +use thread_local_reentrant::AccessError as TlsAccessError; + +pub type RawThreadHandle = ArcLite< ThreadData >; + +struct ThreadRegistry { + enabled_for_new_threads: bool, + threads_by_system_id: Option< HashMap< u32, RawThreadHandle > >, + new_dead_thread_queue: Vec< (Timestamp, RawThreadHandle) >, + thread_counter: u64 +} + +unsafe impl Send for ThreadRegistry {} + +impl ThreadRegistry { + fn threads_by_system_id( &mut self ) -> &mut HashMap< u32, RawThreadHandle > { + self.threads_by_system_id.get_or_insert_with( HashMap::new ) + } +} + +const STATE_UNINITIALIZED: usize = 0; +const STATE_INITIALIZING_STAGE_1: usize = 1; +const STATE_PARTIALLY_INITIALIZED: usize = 2; +const STATE_INITIALIZING_STAGE_2: usize = 3; +const STATE_DISABLED: usize = 4; +const STATE_STARTING: usize = 5; +const STATE_ENABLED: usize = 6; +const STATE_STOPPING: usize = 7; +const STATE_PERMANENTLY_DISABLED: usize = 8; +static STATE: AtomicUsize = AtomicUsize::new( STATE_UNINITIALIZED ); + +static THREAD_RUNNING: AtomicBool = AtomicBool::new( false ); + +const DESIRED_STATE_DISABLED: usize = 0; +const DESIRED_STATE_SUSPENDED: usize = 1; +const DESIRED_STATE_ENABLED: usize = 2; +static DESIRED_STATE: AtomicUsize = AtomicUsize::new( DESIRED_STATE_DISABLED ); + +static THREAD_REGISTRY: SpinLock< ThreadRegistry > = SpinLock::new( ThreadRegistry { + enabled_for_new_threads: false, + threads_by_system_id: None, + new_dead_thread_queue: Vec::new(), + thread_counter: 1 +}); + +#[inline(never)] +fn lock_thread_registry< R >( callback: impl FnOnce( &mut ThreadRegistry ) -> R ) -> R { + callback( &mut THREAD_REGISTRY.lock() ) +} + +static PROCESSING_THREAD_HANDLE: SpinLock< Option< libc::pthread_t > > = SpinLock::new( None ); + +pub static mut SYM_REGISTER_FRAME: Option< unsafe extern "C" fn( fde: *const u8 ) > = None; +pub static mut SYM_DEREGISTER_FRAME: Option< unsafe extern "C" fn( fde: *const u8 ) > = None; + +pub static MMAP_LOCK: SpinLock< () > = SpinLock::new(()); + +#[cfg(feature = "jemalloc")] +#[inline] +pub fn using_unprefixed_jemalloc() -> bool { + true +} + +#[cfg(not(feature = "jemalloc"))] +static USING_UNPREFIXED_JEMALLOC: AtomicBool = AtomicBool::new( false ); + +#[cfg(not(feature = "jemalloc"))] +#[inline] +pub fn using_unprefixed_jemalloc() -> bool { + USING_UNPREFIXED_JEMALLOC.load( Ordering::Relaxed ) +} + +pub fn toggle() { + if STATE.load( Ordering::SeqCst ) == STATE_PERMANENTLY_DISABLED { + return; + } + + let value = DESIRED_STATE.load( Ordering::SeqCst ); + let new_value = match value { + DESIRED_STATE_DISABLED => { + info!( "Tracing will be toggled ON (for the first time)" ); + DESIRED_STATE_ENABLED + }, + DESIRED_STATE_SUSPENDED => { + info!( "Tracing will be toggled ON" ); + DESIRED_STATE_ENABLED + }, + DESIRED_STATE_ENABLED => { + info!( "Tracing will be toggled OFF" ); + DESIRED_STATE_SUSPENDED + }, + _ => unreachable!() + }; + + DESIRED_STATE.store( new_value, Ordering::SeqCst ); +} + +pub fn enable() -> bool { + if STATE.load( Ordering::SeqCst ) == STATE_PERMANENTLY_DISABLED { + return false; + } + + DESIRED_STATE.swap( DESIRED_STATE_ENABLED, Ordering::SeqCst ) != DESIRED_STATE_ENABLED +} + +pub fn disable() -> bool { + if STATE.load( Ordering::SeqCst ) == STATE_PERMANENTLY_DISABLED { + return false; + } + + DESIRED_STATE.swap( DESIRED_STATE_SUSPENDED, Ordering::SeqCst ) == DESIRED_STATE_ENABLED +} + +fn is_busy() -> bool { + let state = STATE.load( Ordering::SeqCst ); + if state == STATE_STARTING || state == STATE_STOPPING { + return true; + } + + let requested_state = DESIRED_STATE.load( Ordering::SeqCst ); + let is_thread_running = THREAD_RUNNING.load( Ordering::SeqCst ); + if requested_state == DESIRED_STATE_DISABLED && is_thread_running && state == STATE_ENABLED { + return true; + } + + false +} + +fn try_sync_processing_thread_destruction() { + let mut handle = PROCESSING_THREAD_HANDLE.lock(); + let state = STATE.load( Ordering::SeqCst ); + if state == STATE_STOPPING || state == STATE_DISABLED { + if let Some( handle ) = handle.take() { + unsafe { + libc::pthread_join( handle, std::ptr::null_mut() ); + } + } + } +} + +pub fn sync() { + try_sync_processing_thread_destruction(); + + while is_busy() { + thread::sleep( std::time::Duration::from_millis( 1 ) ); + } + + try_sync_processing_thread_destruction(); +} + +pub extern fn on_exit() { + if STATE.load( Ordering::SeqCst ) == STATE_PERMANENTLY_DISABLED { + return; + } + + info!( "Exit hook called" ); + + DESIRED_STATE.store( DESIRED_STATE_DISABLED, Ordering::SeqCst ); + send_event( InternalEvent::Exit ); + + let mut count = 0; + while THREAD_RUNNING.load( Ordering::SeqCst ) == true && count < 2000 { + unsafe { + libc::usleep( 25 * 1000 ); + count += 1; + } + } + + info!( "Exit hook finished" ); +} + +pub unsafe extern fn on_fork() { + STATE.store( STATE_PERMANENTLY_DISABLED, Ordering::SeqCst ); + DESIRED_STATE.store( DESIRED_STATE_DISABLED, Ordering::SeqCst ); + THREAD_RUNNING.store( false, Ordering::SeqCst ); + THREAD_REGISTRY.force_unlock(); // In case we were forked when the lock was held. + { + let tid = syscall::gettid(); + let mut registry = THREAD_REGISTRY.lock(); + registry.enabled_for_new_threads = false; + registry.threads_by_system_id().retain( |&_, thread| { + thread.thread_id == tid + }); + } + + let _ = TLS.try_with( |tls| tls.set_enabled( false ) ); +} + +fn spawn_processing_thread() { + info!( "Spawning event processing thread..." ); + + let mut thread_handle = PROCESSING_THREAD_HANDLE.lock(); + assert!( !THREAD_RUNNING.load( Ordering::SeqCst ) ); + + extern "C" fn thread_main( _: *mut libc::c_void ) -> *mut libc::c_void { + TLS.try_with( |tls| { + unsafe { + *tls.is_internal.get() = true; + } + assert!( !tls.is_enabled() ); + }).unwrap(); + + THREAD_RUNNING.store( true, Ordering::SeqCst ); + + let result = std::panic::catch_unwind( || { + crate::processing_thread::thread_main(); + }); + + if result.is_err() { + DESIRED_STATE.store( DESIRED_STATE_DISABLED, Ordering::SeqCst ); + } + + lock_thread_registry( |thread_registry| { + thread_registry.enabled_for_new_threads = false; + for tls in thread_registry.threads_by_system_id().values() { + if tls.is_internal() { + continue; + } + + debug!( "Disabling thread {:04x}...", tls.thread_id ); + tls.set_enabled( false ); + } + + STATE.store( STATE_DISABLED, Ordering::SeqCst ); + info!( "Tracing was disabled" ); + + THREAD_RUNNING.store( false, Ordering::SeqCst ); + }); + + if let Err( err ) = result { + std::panic::resume_unwind( err ); + } + + std::ptr::null_mut() + } + + let mut thread: libc::pthread_t; + unsafe { + thread = std::mem::zeroed(); + if libc::pthread_create( &mut thread, std::ptr::null(), thread_main, std::ptr::null_mut() ) < 0 { + panic!( "failed to start the main memory profiler thread: {}", std::io::Error::last_os_error() ); + } + if libc::pthread_setname_np( thread, b"mem-prof".as_ptr() as *const libc::c_char ) < 0 { + warn!( "Failed to set the name of the processing thread: {}", std::io::Error::last_os_error() ); + } + } + + while THREAD_RUNNING.load( Ordering::SeqCst ) == false { + thread::yield_now(); + } + + *thread_handle = Some( thread ); +} + +#[cfg(target_arch = "x86_64")] +fn find_internal_syms< const N: usize >( names: &[&str; N] ) -> [usize; N] { + let mut addresses = [0; N]; + + unsafe { + use goblin::elf64::header::Header; + use goblin::elf64::section_header::SectionHeader; + use goblin::elf::section_header::{SHT_DYNSYM, SHT_SYMTAB}; + use goblin::elf::sym::sym64::Sym; + + let self_path = b"/proc/self/exe\0".as_ptr() as _; + let mut fd = crate::syscall::open_raw_cstr( self_path, libc::O_RDONLY, 0 ); + if fd < 0 { + warn!( "failed to open /proc/self/exe: {}", std::io::Error::from_raw_os_error( fd ) ); + let path = libc::getauxval( libc::AT_EXECFN ) as *const libc::c_char; + if !path.is_null() { + fd = crate::syscall::open_raw_cstr( path, libc::O_RDONLY, 0 ); + if fd < 0 { + panic!( "failed to open {:?}: {}", std::ffi::CStr::from_ptr( path ), std::io::Error::from_raw_os_error( fd ) ); + } + } else { + panic!( "couldn't open /proc/self/exe" ); + } + } + + let mut buf: libc::stat64 = std::mem::zeroed(); + if libc::fstat64( fd as _, &mut buf ) != 0 { + panic!( "couldn't fstat the executable: {}", std::io::Error::last_os_error() ); + } + + let size = buf.st_size as usize; + let executable = syscall::mmap( std::ptr::null_mut(), size, libc::PROT_READ, libc::MAP_PRIVATE, fd, 0 ); + assert_ne!( executable, libc::MAP_FAILED ); + + let elf_header = *(executable as *const Header); + let address_offset = libc::getauxval( libc::AT_PHDR ) as usize - elf_header.e_phoff as usize; + + assert_eq!( elf_header.e_shentsize as usize, std::mem::size_of::< SectionHeader >() ); + let section_headers = std::slice::from_raw_parts( + ((executable as *const u8).add( elf_header.e_shoff as usize )) as *const SectionHeader, + elf_header.e_shnum as usize + ); + + for section_header in section_headers { + if section_header.sh_type != SHT_SYMTAB && section_header.sh_type != SHT_DYNSYM { + continue; + } + let strtab_key = section_header.sh_link as usize; + let strtab_section_header = section_headers[ strtab_key ]; + let strtab_bytes = std::slice::from_raw_parts( (executable as *const u8).add( strtab_section_header.sh_offset as usize ), strtab_section_header.sh_size as usize ); + + let syms = std::slice::from_raw_parts( + (executable as *const u8).add( section_header.sh_offset as usize ) as *const Sym, + section_header.sh_size as usize / std::mem::size_of::< Sym >() + ); + + for sym in syms { + let bytes = &strtab_bytes[ sym.st_name as usize.. ]; + let name = &bytes[ ..bytes.iter().position( |&byte| byte == 0 ).unwrap_or( bytes.len() ) ]; + for (target_name, output_address) in names.iter().zip( addresses.iter_mut() ) { + if *output_address != 0 { + continue; + } + if name == target_name.as_bytes() { + if let Some( address ) = address_offset.checked_add( sym.st_value as usize ) { + info!( "Found '{}' at: 0x{:016X}", target_name, address ); + *output_address = address; + break; + } + } + } + } + } + + let errcode = syscall::munmap( executable, size ); + if errcode < 0 { + warn!( "munmap failed: {}", std::io::Error::from_raw_os_error( errcode ) ); + } + + let errcode = syscall::close( fd ); + if errcode < 0 { + warn!( "close failed: {}", std::io::Error::from_raw_os_error( errcode ) ); + } + } + + addresses +} + +#[cfg(target_arch = "x86_64")] +fn hook_jemalloc() { + let names = [ + "_rjem_malloc", + "_rjem_mallocx", + "_rjem_calloc", + "_rjem_sdallocx", + "_rjem_realloc", + "_rjem_rallocx", + "_rjem_nallocx", + "_rjem_xallocx", + "_rjem_malloc_usable_size", + "_rjem_mallctl", + "_rjem_posix_memalign", + "_rjem_aligned_alloc", + "_rjem_free", + "_rjem_sallocx", + "_rjem_dallocx", + "_rjem_mallctlnametomib", + "_rjem_mallctlbymib", + "_rjem_malloc_stats_print", + "_rjem_memalign", + "_rjem_valloc", + + "malloc", + "mallocx", + "calloc", + "sdallocx", + "realloc", + "rallocx", + "nallocx", + "xallocx", + "malloc_usable_size", + "mallctl", + "posix_memalign", + "aligned_alloc", + "free", + "sallocx", + "dallocx", + "mallctlnametomib", + "mallctlbymib", + "malloc_stats_print", + "memalign", + "valloc", + ]; + + let replacements = [ + // Prefixed jemalloc. + crate::api::_rjem_malloc as usize, + crate::api::_rjem_mallocx as usize, + crate::api::_rjem_calloc as usize, + crate::api::_rjem_sdallocx as usize, + crate::api::_rjem_realloc as usize, + crate::api::_rjem_rallocx as usize, + crate::api::_rjem_nallocx as usize, + crate::api::_rjem_xallocx as usize, + crate::api::_rjem_malloc_usable_size as usize, + crate::api::_rjem_mallctl as usize, + crate::api::_rjem_posix_memalign as usize, + crate::api::_rjem_aligned_alloc as usize, + crate::api::_rjem_free as usize, + crate::api::_rjem_sallocx as usize, + crate::api::_rjem_dallocx as usize, + crate::api::_rjem_mallctlnametomib as usize, + crate::api::_rjem_mallctlbymib as usize, + crate::api::_rjem_malloc_stats_print as usize, + crate::api::_rjem_memalign as usize, + crate::api::_rjem_valloc as usize, + + // Unprefixed jemalloc. + crate::api::_rjem_malloc as usize, + crate::api::_rjem_mallocx as usize, + crate::api::_rjem_calloc as usize, + crate::api::_rjem_sdallocx as usize, + crate::api::_rjem_realloc as usize, + crate::api::_rjem_rallocx as usize, + crate::api::_rjem_nallocx as usize, + crate::api::_rjem_xallocx as usize, + crate::api::_rjem_malloc_usable_size as usize, + crate::api::_rjem_mallctl as usize, + crate::api::_rjem_posix_memalign as usize, + crate::api::_rjem_aligned_alloc as usize, + crate::api::_rjem_free as usize, + crate::api::_rjem_sallocx as usize, + crate::api::_rjem_dallocx as usize, + crate::api::_rjem_mallctlnametomib as usize, + crate::api::_rjem_mallctlbymib as usize, + crate::api::_rjem_malloc_stats_print as usize, + crate::api::_rjem_memalign as usize, + crate::api::_rjem_valloc as usize, + ]; + + let addresses = find_internal_syms( &names ); + if addresses.iter().all( |&address| address == 0 ) { + return; + } + + let index_mallocx = names.iter().position( |name| *name == "mallocx" ).unwrap(); + let index_sdallocx = names.iter().position( |name| *name == "sdallocx" ).unwrap(); + let index_rallocx = names.iter().position( |name| *name == "rallocx" ).unwrap(); + + let enable_extended_hooks = + addresses[ index_mallocx ] != 0 || + addresses[ index_sdallocx ] != 0 || + addresses[ index_rallocx ] != 0; + + let extended_hooks_offset = names.iter().position( |name| !name.starts_with( "_rjem_" ) ).unwrap(); + + if enable_extended_hooks { + info!( "Attaching prefixed jemalloc hooks..." ); + hook_symbols( &names, &addresses, &replacements ); + } else { + info!( "Attaching unprefixed jemalloc hooks..." ); + hook_symbols( &names[ ..extended_hooks_offset ], &addresses[ ..extended_hooks_offset ], &replacements[ ..extended_hooks_offset ] ); + + #[cfg(not(feature = "jemalloc"))] + USING_UNPREFIXED_JEMALLOC.store( true, Ordering::SeqCst ); + } +} + +#[cfg(target_arch = "x86_64")] +fn hook_symbols( names: &[&str], addresses: &[usize], replacements: &[usize] ) { + assert_eq!( names.len(), replacements.len() ); + assert_eq!( names.len(), addresses.len() ); + + for ((&name, &replacement), &address) in names.iter().zip( replacements ).zip( addresses ) { + if address == 0 { + info!( "Symbol not found: \"{}\"", name ); + continue; + } + + if replacement == address { + panic!( "tried to replace a symbol with itself: symbol='{}', address=0x{:016X}", name, replacement ); + } + + let page = (address as usize & !(4096 - 1)) as *mut libc::c_void; + unsafe { + if libc::mprotect( page, 4096, libc::PROT_READ | libc::PROT_WRITE | libc::PROT_EXEC ) < 0 { + panic!( "mprotect failed: {}", std::io::Error::last_os_error() ); + } + + // Write a `jmp` instruction with a RIP-relative addressing mode, with a zero displacement. + let mut p = address as *mut u8; + std::ptr::write_unaligned( p, 0xFF ); p = p.add( 1 ); + std::ptr::write_unaligned( p, 0x25 ); p = p.add( 1 ); + std::ptr::write_unaligned( p, 0x00 ); p = p.add( 1 ); + std::ptr::write_unaligned( p, 0x00 ); p = p.add( 1 ); + std::ptr::write_unaligned( p, 0x00 ); p = p.add( 1 ); + std::ptr::write_unaligned( p, 0x00 ); p = p.add( 1 ); + std::ptr::write_unaligned( p as *mut usize, replacement ); + + if libc::mprotect( page, 4096, libc::PROT_READ | libc::PROT_EXEC ) < 0 { + warn!( "mprotect failed: {}", std::io::Error::last_os_error() ); + } + } + } +} + +fn resolve_original_syms() { + unsafe { + let register_frame = libc::dlsym( libc::RTLD_NEXT, b"__register_frame\0".as_ptr() as *const libc::c_char ); + let deregister_frame = libc::dlsym( libc::RTLD_NEXT, b"__deregister_frame\0".as_ptr() as *const libc::c_char ); + if register_frame.is_null() || deregister_frame.is_null() { + if register_frame.is_null() { + warn!( "Failed to find `__register_frame` symbol" ); + } + if deregister_frame.is_null() { + warn!( "Failed to find `__deregister_frame` symbol" ); + } + return; + } + + crate::global::SYM_REGISTER_FRAME = Some( std::mem::transmute( register_frame ) ); + crate::global::SYM_DEREGISTER_FRAME = Some( std::mem::transmute( deregister_frame ) ); + } +} + +fn initialize_stage_1() { + crate::init::initialize_logger(); + info!( "Version: {}", env!( "CARGO_PKG_VERSION" ) ); + + unsafe { + crate::opt::initialize(); + } + + if !crate::opt::get().disabled_by_default { + toggle(); + } + + #[cfg(target_arch = "x86_64")] + hook_jemalloc(); + + info!( "Stage 1 initialization finished" ); +} + +fn initialize_stage_2() { + info!( "Initializing stage 2..." ); + + crate::init::initialize_atexit_hook(); + crate::init::initialize_signal_handlers(); + + if !opt::get().track_child_processes { + std::env::remove_var( "LD_PRELOAD" ); + } + + info!( "Stage 2 initialization finished" ); +} + +static ALLOW_STAGE_2: AtomicBool = AtomicBool::new( false ); + +#[used] +#[link_section = ".init_array.00099"] +static INIT_ARRAY: unsafe extern "C" fn( libc::c_int, *mut *mut u8, *mut *mut u8 ) = { + unsafe extern "C" fn function( _argc: libc::c_int, _argv: *mut *mut u8, _envp: *mut *mut u8 ) { + ALLOW_STAGE_2.store( true, Ordering::SeqCst ); + } + function +}; + +#[cold] +#[inline(never)] +fn try_enable( mut state: usize ) -> bool { + if state == STATE_UNINITIALIZED { + if STATE.compare_exchange( STATE_UNINITIALIZED, STATE_INITIALIZING_STAGE_1, Ordering::SeqCst, Ordering::SeqCst ).is_ok() { + initialize_stage_1(); + STATE.store( STATE_PARTIALLY_INITIALIZED, Ordering::SeqCst ); + state = STATE_PARTIALLY_INITIALIZED; + } else { + return false; + } + } + + if state == STATE_PARTIALLY_INITIALIZED { + if !ALLOW_STAGE_2.load( Ordering::SeqCst ) { + return false; + } + + if STATE.compare_exchange( STATE_PARTIALLY_INITIALIZED, STATE_INITIALIZING_STAGE_2, Ordering::SeqCst, Ordering::SeqCst ).is_ok() { + initialize_stage_2(); + STATE.store( STATE_DISABLED, Ordering::SeqCst ); + } else { + return false; + } + } + + if DESIRED_STATE.load( Ordering::SeqCst ) == DESIRED_STATE_DISABLED { + return false; + } + + if STATE.compare_exchange( STATE_DISABLED, STATE_STARTING, Ordering::SeqCst, Ordering::SeqCst ).is_err() { + return false; + } + + static LOCK: SpinLock< () > = SpinLock::new(()); + let mut _lock = match LOCK.try_lock() { + Some( guard ) => guard, + None => { + return false; + } + }; + + lock_thread_registry( |thread_registry| { + assert!( !thread_registry.enabled_for_new_threads ); + }); + + prepare_to_start_unwinding(); + spawn_processing_thread(); + + lock_thread_registry( |thread_registry| { + thread_registry.enabled_for_new_threads = true; + for tls in thread_registry.threads_by_system_id().values() { + if tls.is_internal() { + continue; + } + + debug!( "Enabling thread {:04x}...", tls.thread_id ); + tls.set_enabled( true ); + } + }); + + resolve_original_syms(); + + crate::allocation_tracker::initialize(); + + STATE.store( STATE_ENABLED, Ordering::SeqCst ); + info!( "Tracing was enabled" ); + + true +} + +pub fn try_disable_if_requested() { + if DESIRED_STATE.load( Ordering::SeqCst ) != DESIRED_STATE_DISABLED { + return; + } + + if STATE.compare_exchange( STATE_ENABLED, STATE_STOPPING, Ordering::SeqCst, Ordering::SeqCst ).is_err() { + return; + } + + send_event( InternalEvent::Exit ); +} + +const THROTTLE_LIMIT: usize = 8192; + +#[cold] +#[inline(never)] +fn throttle( tls: &RawThreadHandle ) { + while ArcLite::get_refcount_relaxed( tls ) >= THROTTLE_LIMIT { + thread::yield_now(); + } +} + +pub fn is_actively_running() -> bool { + DESIRED_STATE.load( Ordering::Relaxed ) == DESIRED_STATE_ENABLED +} + +/// A handle to per-thread storage; you can't do anything with it. +/// +/// Can be sent to other threads. +pub struct WeakThreadHandle( RawThreadHandle ); +unsafe impl Send for WeakThreadHandle {} +unsafe impl Sync for WeakThreadHandle {} + +impl WeakThreadHandle { + pub fn system_tid( &self ) -> u32 { + self.0.thread_id + } +} + +/// A handle to per-thread storage. +/// +/// Can only be aquired for the current thread, and cannot be sent to other threads. +pub struct StrongThreadHandle( Option< RawThreadHandle > ); + +impl StrongThreadHandle { + #[cold] + #[inline(never)] + fn acquire_slow() -> Option< Self > { + let current_thread_id = syscall::gettid(); + lock_thread_registry( |thread_registry| { + if let Some( thread ) = thread_registry.threads_by_system_id().get( ¤t_thread_id ) { + debug!( "Acquired a dead thread: {:04X}", current_thread_id ); + Some( StrongThreadHandle( Some( thread.clone() ) ) ) + } else { + warn!( "Failed to acquire a handle for thread: {:04X}", current_thread_id ); + None + } + }) + } + + #[inline(always)] + pub fn acquire() -> Option< Self > { + let state = STATE.load( Ordering::Relaxed ); + if state != STATE_ENABLED { + if !try_enable( state ) { + return None; + } + } + + let tls = TLS.try_with( |tls| { + if ArcLite::get_refcount_relaxed( tls ) >= THROTTLE_LIMIT { + throttle( tls ); + } + + if !tls.is_enabled() { + None + } else { + tls.set_enabled( false ); + Some( tls.0.clone() ) + } + }); + + match tls { + Ok( Some( tls ) ) => { + Some( StrongThreadHandle( Some( tls ) ) ) + }, + Ok( None ) | Err( TlsAccessError::Uninitialized ) => { + None + }, + Err( TlsAccessError::Destroyed ) => { + Self::acquire_slow() + } + } + } + + pub fn decay( mut self ) -> WeakThreadHandle { + let tls = match self.0.take() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + tls.set_enabled( true ); + WeakThreadHandle( tls ) + } + + pub fn unwind_state( &mut self ) -> &mut ThreadUnwindState { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + unsafe { + &mut *tls.unwind_state.get() + } + } + + pub fn on_new_allocation( &mut self ) -> InternalAllocationId { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + let counter = tls.allocation_counter.get(); + let allocation; + unsafe { + allocation = *counter; + *counter += 1; + } + + InternalAllocationId::new( tls.internal_thread_id, allocation ) + } + + pub fn system_tid( &self ) -> u32 { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + tls.thread_id + } + + pub fn unique_tid( &self ) -> u64 { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + tls.internal_thread_id + } + + pub fn allocation_tracker( &self ) -> &AllocationTracker { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + &tls.allocation_tracker + } + + pub(crate) fn zombie_events( &self ) -> &SpinLock< Vec< InternalEvent > > { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + &tls.zombie_events + } + + pub fn is_dead( &self ) -> bool { + let tls = match self.0.as_ref() { + Some( tls ) => tls, + None => unsafe { std::hint::unreachable_unchecked() } + }; + + tls.is_dead.load( Ordering::Relaxed ) + } +} + +impl Drop for StrongThreadHandle { + fn drop( &mut self ) { + if let Some( tls ) = self.0.take() { + tls.set_enabled( true ); + } + } +} + +pub struct AllocationLock { + current_thread_id: u32, + registry_lock: SpinLockGuard< 'static, ThreadRegistry > +} + +impl AllocationLock { + pub fn new() -> Self { + let mut registry_lock = THREAD_REGISTRY.lock(); + let current_thread_id = syscall::gettid(); + let threads = registry_lock.threads_by_system_id(); + for (&thread_id, tls) in threads.iter_mut() { + if thread_id == current_thread_id { + continue; + } + + if tls.is_internal() { + continue; + } + unsafe { + ArcLite::add( tls, THROTTLE_LIMIT ); + } + } + + std::sync::atomic::fence( Ordering::SeqCst ); + + for (&thread_id, tls) in threads.iter_mut() { + if thread_id == current_thread_id { + continue; + } + + if tls.is_internal() { + continue; + } + while ArcLite::get_refcount_relaxed( tls ) != THROTTLE_LIMIT { + thread::yield_now(); + } + } + + std::sync::atomic::fence( Ordering::SeqCst ); + + AllocationLock { + current_thread_id, + registry_lock + } + } +} + +impl Drop for AllocationLock { + fn drop( &mut self ) { + for (&thread_id, tls) in self.registry_lock.threads_by_system_id().iter_mut() { + if thread_id == self.current_thread_id { + continue; + } + + unsafe { + ArcLite::sub( tls, THROTTLE_LIMIT ); + } + } + } +} + +pub struct ThreadData { + thread_id: u32, + internal_thread_id: u64, + is_internal: UnsafeCell< bool >, + enabled: AtomicBool, + is_dead: AtomicBool, + unwind_state: UnsafeCell< ThreadUnwindState >, + allocation_counter: UnsafeCell< u64 >, + allocation_tracker: AllocationTracker, + zombie_events: SpinLock< Vec< InternalEvent > > +} + +impl ThreadData { + #[inline(always)] + pub fn is_enabled( &self ) -> bool { + self.enabled.load( Ordering::Relaxed ) + } + + #[inline(always)] + pub fn is_internal( &self ) -> bool { + unsafe { + *self.is_internal.get() + } + } + + fn set_enabled( &self, value: bool ) { + self.enabled.store( value, Ordering::Relaxed ) + } +} + +struct ThreadSentinel( RawThreadHandle ); + +impl Deref for ThreadSentinel { + type Target = RawThreadHandle; + fn deref( &self ) -> &Self::Target { + &self.0 + } +} + +impl Drop for ThreadSentinel { + fn drop( &mut self ) { + self.is_dead.store( true, Ordering::SeqCst ); + + let is_enabled = self.enabled.load( Ordering::SeqCst ); + self.enabled.store( false, Ordering::SeqCst ); + + lock_thread_registry( |thread_registry| { + if let Some( thread ) = thread_registry.threads_by_system_id().get( &self.thread_id ) { + let thread = thread.clone(); + thread_registry.new_dead_thread_queue.push( (crate::timestamp::get_timestamp(), thread) ); + } + }); + + debug!( "Thread dropped: {:04X}", self.thread_id ); + self.enabled.store( is_enabled, Ordering::SeqCst ); + } +} + +thread_local_reentrant! { + static TLS: ThreadSentinel = |callback| { + let thread_id = syscall::gettid(); + let tls = lock_thread_registry( |registry| { + let internal_thread_id = registry.thread_counter; + registry.thread_counter += 1; + + let tls = ThreadData { + thread_id, + internal_thread_id, + is_internal: UnsafeCell::new( false ), + is_dead: AtomicBool::new( false ), + enabled: AtomicBool::new( registry.enabled_for_new_threads ), + unwind_state: UnsafeCell::new( ThreadUnwindState::new() ), + allocation_counter: UnsafeCell::new( 1 ), + allocation_tracker: crate::allocation_tracker::on_thread_created( internal_thread_id ), + zombie_events: SpinLock::new( Vec::new() ) + }; + + let tls = ArcLite::new( tls ); + registry.threads_by_system_id().insert( thread_id, tls.clone() ); + + tls + }); + + callback( ThreadSentinel( tls ) ) + }; +} + +#[derive(Default)] +pub struct ThreadGarbageCollector { + buffer: Vec< (Timestamp, RawThreadHandle) >, + dead_threads: Vec< (Timestamp, RawThreadHandle) >, +} + +impl ThreadGarbageCollector { + pub(crate) fn run( &mut self, now: Timestamp, events: &mut Vec< InternalEvent > ) { + use std::collections::hash_map::Entry; + + lock_thread_registry( |thread_registry| { + std::mem::swap( &mut thread_registry.new_dead_thread_queue, &mut self.buffer ); + }); + + for (timestamp, thread) in self.buffer.drain( .. ) { + crate::allocation_tracker::on_thread_destroyed( thread.internal_thread_id ); + events.extend( thread.zombie_events.lock().drain( .. ) ); + self.dead_threads.push( (timestamp, thread) ); + } + + if self.dead_threads.is_empty() { + return; + } + + let count = self.dead_threads.iter() + .take_while( |&(time_of_death, _)| time_of_death.as_secs() + 3 < now.as_secs() ) + .count(); + + if count == 0 { + return; + } + + for (_, thread) in self.dead_threads.drain( ..count ) { + lock_thread_registry( |thread_registry| { + let mut entry_by_system_id = None; + if let Entry::Occupied( entry ) = thread_registry.threads_by_system_id.as_mut().unwrap().entry( thread.thread_id ) { + if RawThreadHandle::ptr_eq( entry.get(), &thread ) { + entry_by_system_id = Some( entry.remove_entry() ); + } + } + + entry_by_system_id + }); + } + } +} diff --git a/preload-syscaller/src/init.rs b/preload-syscaller/src/init.rs new file mode 100644 index 00000000..2b8d0359 --- /dev/null +++ b/preload-syscaller/src/init.rs @@ -0,0 +1,81 @@ +use crate::global::on_exit; +use crate::logger; +use crate::opt; +use crate::utils::generate_filename; + +pub static mut SYSCALL_LOGGER: logger::SyscallLogger = logger::SyscallLogger::empty(); +pub static mut FILE_LOGGER: logger::FileLogger = logger::FileLogger::empty(); + +pub fn initialize_logger() { + let log_level = if let Some( value ) = unsafe { crate::syscall::getenv( b"MEMORY_PROFILER_LOG" ) } { + match value.to_str() { + Some( "trace" ) => log::LevelFilter::Trace, + Some( "debug" ) => log::LevelFilter::Debug, + Some( "info" ) => log::LevelFilter::Info, + Some( "warn" ) => log::LevelFilter::Warn, + Some( "error" ) => log::LevelFilter::Error, + _ => log::LevelFilter::Off + } + } else { + log::LevelFilter::Off + }; + + let pid = crate::syscall::getpid(); + unsafe { + SYSCALL_LOGGER.initialize( log_level, pid ); + } + + if let Some( value ) = unsafe { crate::syscall::getenv( b"MEMORY_PROFILER_LOGFILE" ) } { + let path = generate_filename( value.as_slice(), None ); + let rotate_at = unsafe { crate::syscall::getenv( b"MEMORY_PROFILER_LOGFILE_ROTATE_WHEN_BIGGER_THAN" ) }.and_then( |value| value.to_str()?.parse().ok() ); + + unsafe { + if let Ok(()) = FILE_LOGGER.initialize( path, rotate_at, log_level, pid ) { + log::set_logger( &FILE_LOGGER ).unwrap(); + } + } + } else { + unsafe { + log::set_logger( &SYSCALL_LOGGER ).unwrap(); + } + } + + log::set_max_level( log_level ); +} + +pub fn initialize_atexit_hook() { + info!( "Setting atexit hook..." ); + unsafe { + let result = libc::atexit( on_exit ); + if result != 0 { + error!( "Cannot set the at-exit hook" ); + } + } +} + +pub fn initialize_signal_handlers() { + extern "C" fn sigusr_handler( signal: libc::c_int ) { + let signal_name = match signal { + libc::SIGUSR1 => "SIGUSR1", + libc::SIGUSR2 => "SIGUSR2", + _ => "???" + }; + + info!( "Signal handler triggered with signal: {} ({})", signal_name, signal ); + crate::global::toggle(); + } + + if opt::get().register_sigusr1 { + info!( "Registering SIGUSR1 handler..." ); + unsafe { + libc::signal( libc::SIGUSR1, sigusr_handler as libc::sighandler_t ); + } + } + + if opt::get().register_sigusr2 { + info!( "Registering SIGUSR2 handler..." ); + unsafe { + libc::signal( libc::SIGUSR2, sigusr_handler as libc::sighandler_t ); + } + } +} diff --git a/preload-syscaller/src/lib.rs b/preload-syscaller/src/lib.rs new file mode 100644 index 00000000..11914223 --- /dev/null +++ b/preload-syscaller/src/lib.rs @@ -0,0 +1,95 @@ +#[macro_use] +extern crate log; + +#[macro_use] +extern crate lazy_static; + +#[cfg(feature = "sc")] +#[macro_use] +extern crate sc; + +#[macro_use] +extern crate thread_local_reentrant; + +use std::fs::read_link; + +use std::os::unix::ffi::OsStrExt; + +#[macro_use] +mod macros; +mod unwind; +mod timestamp; +mod spin_lock; +mod channel; +mod utils; +mod arch; +mod logger; +mod opt; +mod syscall; +mod raw_file; +mod arc_lite; +mod writers; +mod writer_memory; +mod api; +mod event; +mod init; +mod processing_thread; +mod global; +mod ordered_map; +mod nohash; +mod allocation_tracker; + +use crate::event::InternalEvent; +use crate::utils::read_file; + +#[global_allocator] +static mut ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; + +pub(crate) const PAGE_SIZE: usize = 4096; + +lazy_static! { + pub(crate) static ref PID: u32 = { + let pid = crate::syscall::getpid() as u32; + pid + }; + pub(crate) static ref CMDLINE: Vec< u8 > = { + read_file( "/proc/self/cmdline" ).unwrap() + }; + pub(crate) static ref EXECUTABLE: Vec< u8 > = { + let executable: Vec< u8 > = read_link( "/proc/self/exe" ).unwrap().as_os_str().as_bytes().into(); + executable + }; +} + +pub use crate::api::{ + memory_profiler_raw_mmap, + memory_profiler_raw_munmap, + + __register_frame, + __deregister_frame, + + _exit, + _Exit, + fork, + + malloc, + calloc, + realloc, + reallocarray, + free, + posix_memalign, + malloc_usable_size, + mmap, + munmap, + mallopt, + memalign, + aligned_alloc, + valloc, + pvalloc, + + memory_profiler_set_marker, + memory_profiler_override_next_timestamp, + memory_profiler_start, + memory_profiler_stop, + memory_profiler_sync +}; diff --git a/preload-syscaller/src/logger.rs b/preload-syscaller/src/logger.rs new file mode 100644 index 00000000..8c9dc50b --- /dev/null +++ b/preload-syscaller/src/logger.rs @@ -0,0 +1,239 @@ +use std::io::{self, Write}; +use std::mem; +use std::sync::atomic::{AtomicUsize, Ordering}; +use log::{self, Level, Record, Metadata}; +use std::os::unix::io::{IntoRawFd, FromRawFd}; +use libc; + +use crate::utils::{Buffer, stack_format_bytes, temporarily_change_umask}; +use crate::spin_lock::SpinLock; +use crate::raw_file::{RawFile, rename}; +use crate::syscall; + +fn level_to_str( level: Level ) -> &'static str { + match level { + Level::Error => "ERR", + Level::Warn => "WRN", + Level::Info => "INF", + Level::Debug => "DBG", + Level::Trace => "TRC" + } +} + +pub struct SyscallLogger { + level: log::LevelFilter, + pid: libc::pid_t +} + +impl SyscallLogger { + pub const fn empty() -> Self { + SyscallLogger { + level: log::LevelFilter::Off, + pid: 0 + } + } + + pub fn initialize( &mut self, level: log::LevelFilter, pid: libc::pid_t ) { + self.level = level; + self.pid = pid; + } +} + +fn filter( record: &Record ) -> bool { + if let Some( module ) = record.module_path() { + if module.starts_with( "goblin::" ) { + return false; + } + } + + true +} + +fn raw_eprint( buffer: &[u8] ) { + syscall::write( 2, buffer ); +} + +impl log::Log for SyscallLogger { + #[inline] + fn enabled( &self, metadata: &Metadata ) -> bool { + metadata.level() <= self.level + } + + #[inline] + fn log( &self, record: &Record ) { + if self.enabled( record.metadata() ) { + if !filter( record ) { + return; + } + + stack_format_bytes( format_args!( "bytehound: {:04x} {:04x} {} {}\n", self.pid, syscall::gettid(), level_to_str( record.level() ), record.args() ), |buffer| { + buffer[ buffer.len() - 1 ] = b'\n'; + raw_eprint( buffer ); + }); + } + } + + #[inline] + fn flush( &self ) {} +} + +struct RotationState { + path: Buffer, + old_path: Buffer, + initial_path: Buffer, + rotated: bool +} + +impl RotationState { + fn rotate( &mut self ) -> RawFile { + let path = &self.path; + let old_path = if !self.rotated { + self.rotated = true; + &self.initial_path + } else { + &self.old_path + }; + + if let Err( _ ) = rename( path, old_path ) { + raw_eprint( b"bytehound: Failed to rotate the log file!\n" ); + } + + let fp = { + let _handle = temporarily_change_umask( 0o777 ); + RawFile::create( &path, 0o777 ).expect( "failed to recreate the logfile after rotation" ) + }; + + fp.chmod( 0o777 ); + fp + } +} + +pub struct FileLoggerOutput { + raw_fd: AtomicUsize, + rotation: SpinLock< RotationState >, + bytes_written: AtomicUsize, + rotate_at: Option< usize > +} + +impl FileLoggerOutput { + fn new( path: Buffer, mut rotate_at: Option< usize > ) -> Result< Self, io::Error > { + let fp = { + let _handle = temporarily_change_umask( 0o777 ); + RawFile::create( &path, 0o777 )? + }; + + fp.chmod( 0o777 ); + + if rotate_at == Some( 0 ) { + rotate_at = None; + } + + let mut initial_path = Buffer::new(); + initial_path.write( path.as_slice() ).unwrap(); + initial_path.write( b".initial" ).unwrap(); + + let mut old_path = Buffer::new(); + old_path.write( path.as_slice() ).unwrap(); + old_path.write( b".old" ).unwrap(); + + let output = FileLoggerOutput { + raw_fd: AtomicUsize::new( fp.into_raw_fd() as _ ), + rotation: SpinLock::new( RotationState { + path, + old_path, + initial_path, + rotated: false + }), + bytes_written: AtomicUsize::new( 0 ), + rotate_at + }; + + Ok( output ) + } + + fn fd( &self ) -> libc::c_int { + self.raw_fd.load( Ordering::SeqCst ) as libc::c_int + } + + fn rotate_if_necessary( &self ) -> Result< (), io::Error > { + let threshold = match self.rotate_at { + Some( threshold ) => threshold, + None => return Ok(()) + }; + + if self.bytes_written.load( Ordering::Relaxed ) < threshold { + return Ok(()); + } + + let mut rotation = match self.rotation.try_lock() { + Some( rotation ) => rotation, + None => return Ok(()) + }; + + if self.bytes_written.load( Ordering::SeqCst ) < threshold { + return Ok(()); + } + + let new_fp = rotation.rotate(); + let new_fd = new_fp.into_raw_fd(); + let old_fd = self.raw_fd.swap( new_fd as _, Ordering::SeqCst ) as _; + self.bytes_written.store( 0, Ordering::SeqCst ); + + mem::drop( unsafe { RawFile::from_raw_fd( old_fd ) } ); + + Ok(()) + } +} + +pub struct FileLogger { + level: log::LevelFilter, + pid: libc::pid_t, + output: Option< FileLoggerOutput > +} + +impl FileLogger { + pub const fn empty() -> Self { + FileLogger { + level: log::LevelFilter::Off, + pid: 0, + output: None + } + } + + pub fn initialize( &mut self, path: Buffer, rotate_at: Option< usize >, level: log::LevelFilter, pid: libc::pid_t ) -> io::Result< () > { + let output = FileLoggerOutput::new( path, rotate_at )?; + self.level = level; + self.pid = pid; + self.output = Some( output ); + Ok(()) + } +} + +impl log::Log for FileLogger { + #[inline] + fn enabled( &self, metadata: &Metadata ) -> bool { + metadata.level() <= self.level + } + + #[inline] + fn log( &self, record: &Record ) { + if self.enabled( record.metadata() ) { + if !filter( record ) { + return; + } + + if let Some( output ) = self.output.as_ref() { + stack_format_bytes( format_args!( "{:04x} {:04x} {} {}\n", self.pid, syscall::gettid(), level_to_str( record.level() ), record.args() ), |buffer| { + let fd = output.fd(); + let mut fp = RawFile::borrow_raw( &fd ); + let _ = fp.write_all( buffer ); + output.bytes_written.fetch_add( buffer.len(), Ordering::Relaxed ); + }); + let _ = output.rotate_if_necessary(); + } + } + } + + #[inline] + fn flush( &self ) {} +} diff --git a/preload-syscaller/src/macros.rs b/preload-syscaller/src/macros.rs new file mode 100644 index 00000000..c83084fb --- /dev/null +++ b/preload-syscaller/src/macros.rs @@ -0,0 +1,63 @@ +#[inline(never)] +#[cold] +pub fn fatal_error( args: std::fmt::Arguments ) -> ! { + use log::Log; + + let record = log::RecordBuilder::new() + .level( log::Level::Error ) + .args( args ) + .build(); + + unsafe { + crate::init::SYSCALL_LOGGER.log( &record ); + crate::init::FILE_LOGGER.log( &record ); + } + + panic!(); +} + +macro_rules! panic { + () => {{ + $crate::macros::fatal_error( format_args!( + "panic triggered at {}:{}", + std::file!(), std::line!() + )); + }}; + + ($($token:expr),+) => {{ + $crate::macros::fatal_error( format_args!( + "panic triggered at {}:{}: {}", + std::file!(), std::line!(), format!( $($token),+ ) + )); + }}; +} + +macro_rules! assert_eq { + ($lhs: expr, $rhs: expr) => {{ + match (&$lhs, &$rhs) { + (lhs, rhs) => { + if lhs != rhs { + $crate::macros::fatal_error( format_args!( + "assertion failed at {}:{}: {} == {}", + std::file!(), std::line!(), stringify!( $lhs ), stringify!( $rhs ) + )); + } + } + } + }} +} + +macro_rules! assert_ne { + ($lhs: expr, $rhs: expr) => {{ + match (&$lhs, &$rhs) { + (lhs, rhs) => { + if lhs == rhs { + $crate::macros::fatal_error( format_args!( + "assertion failed at {}:{}: {} != {}", + std::file!(), std::line!(), stringify!( $lhs ), stringify!( $rhs ) + )); + } + } + } + }} +} diff --git a/preload-syscaller/src/nohash.rs b/preload-syscaller/src/nohash.rs new file mode 100644 index 00000000..ddfe6494 --- /dev/null +++ b/preload-syscaller/src/nohash.rs @@ -0,0 +1,32 @@ +#[derive(Default)] +pub struct NoHash; + +impl std::hash::BuildHasher for NoHash { + type Hasher = NoHasher; + fn build_hasher( &self ) -> Self::Hasher { + NoHasher( 0 ) + } +} + +pub struct NoHasher( u64 ); +impl std::hash::Hasher for NoHasher { + fn finish( &self ) -> u64 { + self.0 + } + + fn write( &mut self, _bytes: &[u8] ) { + unimplemented!() + } + + fn write_u32( &mut self, value: u32 ) { + self.0 ^= value as u64; + } + + fn write_u64( &mut self, value: u64 ) { + self.0 ^= value; + } + + fn write_usize( &mut self, value: usize ) { + self.0 ^= value as u64; + } +} diff --git a/preload-syscaller/src/opt.rs b/preload-syscaller/src/opt.rs new file mode 100644 index 00000000..68af5d0f --- /dev/null +++ b/preload-syscaller/src/opt.rs @@ -0,0 +1,191 @@ +use crate::utils::Buffer; + +pub struct Opts { + is_initialized: bool, + + pub base_server_port: u16, + pub chown_output_to: Option< u32 >, + pub disabled_by_default: bool, + pub enable_broadcasts: bool, + pub enable_server: bool, + pub enable_shadow_stack: bool, + pub grab_backtraces_on_free: bool, + pub include_file: Option< Buffer >, + pub output_path_pattern: Buffer, + pub register_sigusr1: bool, + pub register_sigusr2: bool, + pub use_perf_event_open: bool, + pub write_binaries_to_output: bool, + pub zero_memory: bool, + pub gather_mmap_calls: bool, + pub backtrace_cache_size_level_1: usize, + pub backtrace_cache_size_level_2: usize, + pub cull_temporary_allocations: bool, + pub temporary_allocation_lifetime_threshold: u64, + pub temporary_allocation_pending_threshold: Option< usize >, + pub track_child_processes: bool +} + +static mut OPTS: Opts = Opts { + is_initialized: false, + + base_server_port: 8100, + chown_output_to: None, + disabled_by_default: false, + enable_broadcasts: false, + enable_server: false, + enable_shadow_stack: true, + grab_backtraces_on_free: true, + include_file: None, + output_path_pattern: Buffer::from_fixed_slice( b"memory-profiling_%e_%t_%p.dat" ), + register_sigusr1: true, + register_sigusr2: true, + use_perf_event_open: true, + write_binaries_to_output: true, + zero_memory: false, + gather_mmap_calls: false, + backtrace_cache_size_level_1: 16 * 1024, + backtrace_cache_size_level_2: 320 * 1024, + cull_temporary_allocations: false, + temporary_allocation_lifetime_threshold: 10000, + temporary_allocation_pending_threshold: None, + track_child_processes: false +}; + +trait ParseVar: Sized { + fn parse_var( value: Buffer ) -> Option< Self >; +} + +impl ParseVar for bool { + fn parse_var( value: Buffer ) -> Option< Self > { + Some( value.as_slice() == b"1" || value.as_slice() == b"true" ) + } +} + +impl ParseVar for u16 { + fn parse_var( value: Buffer ) -> Option< Self > { + value.to_str()?.parse().ok() + } +} + +impl ParseVar for u32 { + fn parse_var( value: Buffer ) -> Option< Self > { + value.to_str()?.parse().ok() + } +} + +impl ParseVar for u64 { + fn parse_var( value: Buffer ) -> Option< Self > { + value.to_str()?.parse().ok() + } +} + +impl ParseVar for usize { + fn parse_var( value: Buffer ) -> Option< Self > { + value.to_str()?.parse().ok() + } +} + +impl ParseVar for Buffer { + fn parse_var( value: Buffer ) -> Option< Self > { + value.to_str().and_then( |value| Buffer::from_slice( value.as_bytes() ) ) + } +} + +impl< T > ParseVar for Option< T > where T: ParseVar { + fn parse_var( value: Buffer ) -> Option< Self > { + if let Some( value ) = T::parse_var( value ) { + Some( Some( value ) ) + } else { + None + } + } +} + +macro_rules! opts { + ($($name:expr => $var:expr),+) => {{ + $( + let var = $var; + let name = $name; + if let Some( new_value ) = crate::syscall::getenv( $name.as_bytes() ).and_then( ParseVar::parse_var ) { + *var = new_value; + } + + info!( " {:40} = {:?}", name, *var ); + )+ + }} +} + +pub unsafe fn initialize() { + info!( "Options:" ); + + let opts = &mut OPTS; + opts! { + "MEMORY_PROFILER_BASE_SERVER_PORT" => &mut opts.base_server_port, + "MEMORY_PROFILER_CHOWN_OUTPUT_TO" => &mut opts.chown_output_to, + "MEMORY_PROFILER_DISABLE_BY_DEFAULT" => &mut opts.disabled_by_default, + "MEMORY_PROFILER_ENABLE_BROADCAST" => &mut opts.enable_broadcasts, + "MEMORY_PROFILER_ENABLE_SERVER" => &mut opts.enable_server, + "MEMORY_PROFILER_GRAB_BACKTRACES_ON_FREE" => &mut opts.grab_backtraces_on_free, + "MEMORY_PROFILER_INCLUDE_FILE" => &mut opts.include_file, + "MEMORY_PROFILER_OUTPUT" => &mut opts.output_path_pattern, + "MEMORY_PROFILER_REGISTER_SIGUSR1" => &mut opts.register_sigusr1, + "MEMORY_PROFILER_REGISTER_SIGUSR2" => &mut opts.register_sigusr2, + "MEMORY_PROFILER_USE_PERF_EVENT_OPEN" => &mut opts.use_perf_event_open, + "MEMORY_PROFILER_USE_SHADOW_STACK" => &mut opts.enable_shadow_stack, + "MEMORY_PROFILER_WRITE_BINARIES_TO_OUTPUT" => &mut opts.write_binaries_to_output, + "MEMORY_PROFILER_ZERO_MEMORY" => &mut opts.zero_memory, + "MEMORY_PROFILER_GATHER_MMAP_CALLS" => &mut opts.gather_mmap_calls, + "MEMORY_PROFILER_BACKTRACE_CACHE_SIZE_LEVEL_1" + => &mut opts.backtrace_cache_size_level_1, + "MEMORY_PROFILER_BACKTRACE_CACHE_SIZE_LEVEL_2" + => &mut opts.backtrace_cache_size_level_2, + "MEMORY_PROFILER_CULL_TEMPORARY_ALLOCATIONS" + => &mut opts.cull_temporary_allocations, + "MEMORY_PROFILER_TEMPORARY_ALLOCATION_LIFETIME_THRESHOLD" + => &mut opts.temporary_allocation_lifetime_threshold, + "MEMORY_PROFILER_TEMPORARY_ALLOCATION_PENDING_THRESHOLD" + => &mut opts.temporary_allocation_pending_threshold, + "MEMORY_PROFILER_TRACK_CHILD_PROCESSES" + => &mut opts.track_child_processes + } + + opts.is_initialized = true; +} + +#[inline] +pub fn get() -> &'static Opts { + let opts = unsafe { &OPTS }; + debug_assert!( opts.is_initialized ); + + opts +} + +#[inline] +pub fn crosscheck_unwind_results_with_libunwind() -> bool { + false +} + +pub fn emit_partial_backtraces() -> bool { + if !cfg!(debug_assertions) { + return true; + } + + lazy_static! { + static ref VALUE: bool = { + let value = unsafe { crate::syscall::getenv( b"MEMORY_PROFILER_EMIT_PARTIAL_BACKTRACES" ) } + .map( |value| value.as_slice() == b"1" ) + .unwrap_or( true ); + + if value { + info!( "Will emit partial backtraces" ); + } else { + info!( "Will NOT emit partial backtraces" ); + } + + value + }; + } + + *VALUE +} diff --git a/preload-syscaller/src/ordered_map.rs b/preload-syscaller/src/ordered_map.rs new file mode 100644 index 00000000..5bd3e14e --- /dev/null +++ b/preload-syscaller/src/ordered_map.rs @@ -0,0 +1,243 @@ +use { + std::{ + collections::{ + hash_map::{ + Entry, + RandomState + }, + HashMap + }, + hash::{ + BuildHasher, + Hash + }, + marker::{ + PhantomData + } + } +}; + +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +struct Item< K, V > { + prev: Option< K >, + next: Option< K >, + value: V +} + +#[derive(Clone, Debug)] +pub struct OrderedMap< K, V, S = RandomState > where K: Copy + PartialEq + Eq + Hash { + first_and_last: Option< (K, K) >, + map: HashMap< K, Item< K, V >, S >, + phantom: PhantomData< S > +} + +impl< K, V, S > Default for OrderedMap< K, V, S > where K: Copy + PartialEq + Eq + Hash, S: BuildHasher + Default { + fn default() -> Self { + OrderedMap { + first_and_last: None, + map: Default::default(), + phantom: PhantomData + } + } +} + +impl< K, V > OrderedMap< K, V, RandomState > where K: Copy + PartialEq + Eq + Hash { + #[allow(dead_code)] + pub fn new() -> Self { + Self::default() + } +} + +impl< K, V, S > OrderedMap< K, V, S > where K: Copy + PartialEq + Eq + Hash, S: BuildHasher { + #[allow(dead_code)] + pub fn is_empty( &self ) -> bool { + debug_assert_eq!( self.first_and_last.is_none(), self.map.is_empty() ); + self.map.is_empty() + } + + pub fn len( &self ) -> usize { + self.map.len() + } + + pub fn get( &self, key: &K ) -> Option< &V > { + self.map.get( key ).map( |item| &item.value ) + } + + pub fn get_mut( &mut self, key: &K ) -> Option< &mut V > { + self.map.get_mut( key ).map( |item| &mut item.value ) + } + + pub fn front_key( &self ) -> Option< K > { + self.first_and_last.map( |(key, _)| key ) + } + + #[allow(dead_code)] + pub fn back_key( &self ) -> Option< K > { + self.first_and_last.map( |(_, key)| key ) + } + + pub fn pop_front( &mut self ) -> Option< (K, V) > { + let key = self.front_key()?; + self.remove( &key ).map( |value| (key, value) ) + } + + pub fn insert( &mut self, key: K, value: V ) -> Option< V > { + match self.map.entry( key ) { + Entry::Occupied( mut bucket ) => { + let (first, last) = self.first_and_last.unwrap(); + + let bucket = bucket.get_mut(); + let old_value = std::mem::replace( &mut bucket.value, value ); + + if key != last { + let old_next = bucket.next.take().unwrap(); + let old_prev = bucket.prev.take(); + + if key == first { + bucket.prev = Some( last ); + self.first_and_last = Some( (old_next, key) ); + } else { + let old_prev = old_prev.unwrap(); + bucket.prev = Some( last ); + self.first_and_last = Some( (first, key) ); + self.map.get_mut( &old_prev ).unwrap().next = Some( old_next ); + } + + self.map.get_mut( &old_next ).unwrap().prev = old_prev; + self.map.get_mut( &last ).unwrap().next = Some( key ); + } + + Some( old_value ) + }, + Entry::Vacant( bucket ) => { + if let Some( (first, last) ) = self.first_and_last { + self.first_and_last = Some( (first, key) ); + bucket.insert( Item { + prev: Some( last ), + next: None, + value + }); + + self.map.get_mut( &last ).unwrap().next = Some( key ); + } else { + self.first_and_last = Some( (key, key) ); + bucket.insert( Item { + prev: None, + next: None, + value + }); + } + + None + } + } + } + + #[allow(dead_code)] + pub fn contains_key( &self, key: &K ) -> bool { + self.map.contains_key( key ) + } + + pub fn remove( &mut self, key: &K ) -> Option< V > { + let key = *key; + if let Some( item ) = self.map.remove( &key ) { + if self.map.is_empty() { + self.first_and_last = None; + return Some( item.value ); + } + + if let Some( next ) = item.next { + self.map.get_mut( &next ).unwrap().prev = item.prev; + } + if let Some( prev ) = item.prev { + self.map.get_mut( &prev ).unwrap().next = item.next; + } + + let (mut first, mut last) = self.first_and_last.unwrap(); + if first == key { + first = item.next.unwrap(); + } + if last == key { + last = item.prev.unwrap(); + } + self.first_and_last = Some( (first, last) ); + + Some( item.value ) + } else { + None + } + } +} + +#[test] +fn test_ordered_copy_map() { + macro_rules! check { + ($map:expr, $expected:expr) => { + let expected: Vec< i32 > = $expected.iter().copied().collect(); + let mut actual_front = Vec::new(); + let mut actual_back = Vec::new(); + + { + let mut map = $map.clone(); + while let Some( key ) = map.front_key() { + map.remove( &key ); + actual_front.push( key ); + } + } + { + let mut map = $map.clone(); + while let Some( key ) = map.back_key() { + map.remove( &key ); + actual_back.push( key ); + } + } + + assert_eq!( actual_front, expected ); + assert_eq!( $map.len(), expected.len() ); + actual_back.reverse(); + assert_eq!( actual_front, actual_back ); + } + } + + macro_rules! insert { + ($map:expr, $key:expr) => { + $map.insert( $key, () ); + } + } + + let mut map = OrderedMap::new(); + check!( map, &[] ); + + insert!( map, 10 ); + check!( map, &[10] ); + + insert!( map, 5 ); + check!( map, &[10, 5] ); + + insert!( map, 15 ); + check!( map, &[10, 5, 15] ); + + insert!( map, 15 ); // Insert one that's already at the end. + check!( map, &[10, 5, 15] ); + + insert!( map, 5 ); // Insert one from the middle. + check!( map, &[10, 15, 5] ); + + insert!( map, 10 ); // Insert one from the start. + check!( map, &[15, 5, 10] ); + + insert!( map, 20 ); + check!( map, &[15, 5, 10, 20] ); + + map.remove( &15 ); // Remove first. + check!( map, &[5, 10, 20] ); + + map.remove( &10 ); // Remove middle. + check!( map, &[5, 20] ); + + map.remove( &20 ); // Remove last. + check!( map, &[5] ); + + map.remove( &5 ); // Remove first and last. + check!( map, &[] ); +} diff --git a/preload-syscaller/src/processing_thread.rs b/preload-syscaller/src/processing_thread.rs new file mode 100644 index 00000000..243cb5a7 --- /dev/null +++ b/preload-syscaller/src/processing_thread.rs @@ -0,0 +1,854 @@ +use std::hash::Hash; +use std::mem; +use std::fs::{self, File, remove_file}; +use std::os::unix::fs::{OpenOptionsExt, PermissionsExt}; +use std::net::{TcpListener, TcpStream, UdpSocket, IpAddr, SocketAddr}; +use std::time::Duration; +use std::path::{Path, PathBuf}; +use std::sync::atomic::AtomicUsize; + +use std::os::unix::io::AsRawFd; + +use std::io::{ + self, + Write, + Seek, + SeekFrom +}; + +use common::speedy::{Writable, Readable}; + +use common::event::{DataId, Event}; +use common::lz4_stream::Lz4Writer; +use common::request::{ + PROTOCOL_VERSION, + Request, + Response, + BroadcastHeader +}; +use common::get_local_ips; + +use crate::{CMDLINE, EXECUTABLE, PID}; +use crate::arch; +use crate::event::{InternalEvent, send_event, timed_recv_all_events}; +use crate::global::AllocationLock; +use crate::opt; +use crate::timestamp::{Timestamp, get_timestamp, get_wall_clock}; +use crate::utils::{ + generate_filename, + copy, + temporarily_change_umask +}; +use crate::writer_memory; +use crate::writers; +use crate::nohash::NoHash; +use crate::unwind::Backtrace; +use crate::allocation_tracker::{AllocationBucket, BufferedAllocation}; + +fn get_hash< T: Hash >( value: T ) -> u64 { + use std::collections::hash_map::DefaultHasher; + use std::hash::Hasher; + let mut hasher = DefaultHasher::new(); + value.hash( &mut hasher ); + hasher.finish() +} + +fn generate_data_id() -> DataId { + let pid = *PID; + let cmdline = &*CMDLINE; + let executable = &*EXECUTABLE; + + let mut timespec = libc::timespec { + tv_sec: 0, + tv_nsec: 0 + }; + + unsafe { + libc::clock_gettime( libc::CLOCK_REALTIME, &mut timespec ); + } + + let a = get_hash( &pid as *const _ as usize ) ^ get_hash( pid ) ^ get_hash( timespec.tv_sec ); + let b = get_hash( cmdline ) ^ get_hash( executable ) ^ get_hash( timespec.tv_nsec ); + + DataId::new( a, b ) +} + +struct Output { + file: Option< (PathBuf, File) >, + clients: Vec< Client > +} + +impl Output { + fn new() -> Self { + Output { + file: None, + clients: Vec::new() + } + } + + fn set_file( &mut self, fp: File, path: PathBuf ) { + self.file = Some( (path, fp) ); + } + + fn is_none( &self ) -> bool { + self.file.is_none() && self.clients.is_empty() + } +} + +fn poll_clients( id: DataId, initial_timestamp: Timestamp, poll_fds: &mut Vec< libc::pollfd >, output: &mut Lz4Writer< Output > ) { + poll_fds.clear(); + + for client in output.inner().clients.iter() { + poll_fds.push( libc::pollfd { + fd: client.stream.as_raw_fd(), + events: libc::POLLIN | libc::POLLHUP, + revents: 0 + }); + } + + let ok = unsafe { libc::poll( poll_fds.as_ptr() as *mut _, poll_fds.len() as _, 0 ) }; + if ok == -1 { + let err = io::Error::last_os_error(); + if err.kind() != io::ErrorKind::Interrupted { + error!( "Poll failed: {}", err ); + return; + } + } + + for (index, poll_fd) in poll_fds.iter().enumerate() { + let pollin = poll_fd.revents & libc::POLLIN != 0; + let pollhup = poll_fd.revents & libc::POLLHUP != 0; + + let client = &mut output.inner_mut_without_flush().clients[ index ]; + if pollhup { + info!( "A client was disconnected" ); + client.running = false; + continue; + } + + if !pollin { + continue; + } + + trace!( "Reading a client's request..." ); + let request = match Request::read_from_stream_unbuffered( &mut client.stream ) { + Ok( request ) => request, + Err( error ) => { + info!( "Failed to read a client request: {}", error ); + client.running = false; + continue; + } + }; + trace!( "Finished reading the request from client" ); + + match request { + Request::StartStreaming => { + let output = &mut output.inner_mut().unwrap(); + let client = &mut output.clients[ index ]; + if let Err( error ) = client.start_streaming( id, initial_timestamp, &mut output.file ) { + info!( "Failed to start streaming to a client: {}", error ); + client.running = false; + } else { + client.streaming = true; + } + }, + Request::TriggerMemoryDump => { + debug!( "Received a TriggerMemoryDump request" ); + send_event( InternalEvent::GrabMemoryDump ); + }, + Request::Ping => { + trace!( "Received a Ping request" ); + if let Err( error ) = Response::Pong.write_to_stream( &mut client.stream ) { + info!( "Failed to respond to a client ping: {}", error ); + client.running = false; + } + } + } + } + + output.inner_mut_without_flush().clients.retain( |client| client.running ); +} + +impl io::Write for Output { + fn write( &mut self, data: &[u8] ) -> io::Result< usize > { + if let Some( (ref path, ref mut fp) ) = self.file { + if let Err( error ) = fp.write_all( data ) { + warn!( "Write to {:?} failed: {}", path, error ); + self.file = None; + } + } + + for mut client in self.clients.iter_mut() { + if !client.running || !client.streaming { + continue; + } + + let result = client.write_all( data ); + if let Err( error ) = result { + client.running = false; + warn!( "Write to client failed: {}", error ); + } + } + + Ok( data.len() ) + } + + fn flush( &mut self ) -> io::Result< () > { + if let Some( (ref path, ref mut fp) ) = self.file { + if let Err( error ) = fp.flush() { + warn!( "Flush of {:?} failed: {}", path, error ); + self.file = None; + } + } + + Ok(()) + } +} + +impl< 'a > io::Write for &'a mut Client { + fn write( &mut self, data: &[u8] ) -> io::Result< usize > { + let length = data.len(); + let response = Response::Data( data.into() ); + let count = response.write_to_stream( &mut self.stream ).map( |_| length )?; + Ok( count ) + } + + fn flush( &mut self ) -> io::Result< () > { + self.stream.flush() + } +} + +struct Client { + stream: TcpStream, + running: bool, + streaming: bool +} + +impl Client { + fn new( id: DataId, initial_timestamp: Timestamp, listener_port: u16, stream: TcpStream ) -> io::Result< Self > { + let mut client = Client { + stream, + running: true, + streaming: false + }; + + Response::Start( broadcast_header( id, initial_timestamp, listener_port ) ).write_to_stream( &mut client.stream )?; + Ok( client ) + } + + fn stream_initial_data( &mut self, id: DataId, initial_timestamp: Timestamp, path: &Path, file: &mut File ) -> io::Result< () > { + if !opt::get().write_binaries_to_output { + info!( "Streaming the binaries which were suppressed in the original output file..." ); + let mut serializer = Lz4Writer::new( &mut *self ); + writers::write_header( id, initial_timestamp, &mut serializer )?; + writers::write_binaries( &mut serializer )?; + serializer.flush()?; + } + + info!( "Streaming initial data..." ); + file.seek( SeekFrom::Start( 0 ) )?; + copy( file, &mut *self )?; + + Response::FinishedInitialStreaming.write_to_stream( &mut self.stream )?; + + if let Err( error ) = remove_file( &path ) { + warn!( "Failed to remove {:?}: {}", path, error ); + } + + info!( "Finished streaming initial data" ); + Ok(()) + } + + fn start_streaming( &mut self, id: DataId, initial_timestamp: Timestamp, output: &mut Option< (PathBuf, File) > ) -> io::Result< () > { + // First client which connects to us gets streamed all of the data + // which we've gathered up until this point. + + if let Some( (path, mut fp) ) = output.take() { + match self.stream_initial_data( id, initial_timestamp, &path, &mut fp ) { + Ok(()) => return Ok(()), + Err( error ) => { + fp.seek( SeekFrom::End( 0 ) )?; + *output = Some( (path, fp) ); + return Err( error ); + } + } + } + + { + let mut serializer = Lz4Writer::new( &mut *self ); + writers::write_header( id, initial_timestamp, &mut serializer )?; + writers::write_maps( &mut serializer )?; + writers::write_binaries( &mut serializer )?; + serializer.flush()?; + } + + Response::FinishedInitialStreaming + .write_to_stream( &mut self.stream )?; + + Ok(()) + } +} + +impl Drop for Client { + fn drop( &mut self ) { + info!( "Removing client..." ); + } +} + +fn broadcast_header( id: DataId, initial_timestamp: Timestamp, listener_port: u16 ) -> BroadcastHeader { + let (timestamp, wall_clock_secs, wall_clock_nsecs) = get_wall_clock(); + + BroadcastHeader { + id, + initial_timestamp, + timestamp, + wall_clock_secs, + wall_clock_nsecs, + pid: *PID, + listener_port, + cmdline: CMDLINE.clone(), + executable: EXECUTABLE.clone(), + arch: arch::TARGET_ARCH.to_string(), + protocol_version: PROTOCOL_VERSION + } +} + +fn create_listener() -> Option< TcpListener > { + let base_port = opt::get().base_server_port; + let mut port = base_port; + + let listener = loop { + match TcpListener::bind( format!( "0.0.0.0:{}", port ) ) { + Ok( listener ) => { + info!( "Created a TCP listener on port {}", port ); + break listener; + }, + Err( error ) => { + port += 1; + if port > base_port + 100 { + error!( "Failed to create a TCP listener: {}", error ); + return None; + } + } + } + }; + + if let Err( error ) = listener.set_nonblocking( true ) { + error!( "Failed to set the TCP listener as non-blocking: {}", error ); + return None; + } + + Some( listener ) +} + +fn send_broadcast_to( id: DataId, initial_timestamp: Timestamp, listener_port: u16, target: IpAddr ) -> Result< (), io::Error > { + let socket = UdpSocket::bind( SocketAddr::new( target, 0 ) )?; + socket.set_broadcast( true )?; + + let mut message = Vec::new(); + broadcast_header( id, initial_timestamp, listener_port ).write_to_stream( &mut message ).unwrap(); + + socket.send_to( &message, "255.255.255.255:43512" )?; + Ok(()) +} + +fn send_broadcast( id: DataId, initial_timestamp: Timestamp, listener_port: u16 ) -> Result< (), io::Error > { + use std::iter::once; + use std::net::Ipv4Addr; + + let wildcard: IpAddr = Ipv4Addr::new( 0, 0, 0, 0 ).into(); + let mut output = Ok(()); + for ip in get_local_ips().into_iter().chain( once( wildcard ) ) { + let result = send_broadcast_to( id, initial_timestamp, listener_port, ip ); + if result.is_err() { + output = result; + } + } + + output +} + +fn initialize_output_file() -> Option< (File, PathBuf) > { + static COUNTER: AtomicUsize = AtomicUsize::new( 0 ); + + let output_path = generate_filename( opt::get().output_path_pattern.as_slice(), Some( &COUNTER ) ); + let output_path = output_path.to_str().unwrap(); + if output_path == "" { + return None; + } + + let fp = { + let _handle = temporarily_change_umask( 0o777 ); + fs::OpenOptions::new() + .read( true ) + .write( true ) + .create( true ) + .truncate( true ) + .mode( 0o777 ) + .open( &output_path ) + }; + + let fp = match fp { + Ok( fp ) => fp, + Err( error ) => { + error!( "Couldn't open '{}' for writing: {}", output_path, error ); + return None; + } + }; + + // In the unlikely case of a race condition when setting the umask. + let _ = fp.set_permissions( fs::Permissions::from_mode( 0o777 ) ); + + info!( "File '{}' opened for writing", output_path ); + if let Some( uid ) = opt::get().chown_output_to { + let gid = unsafe { libc::getgid() }; + let errcode = unsafe { libc::fchown( fp.as_raw_fd(), uid, gid ) }; + if errcode != 0 { + let err = io::Error::last_os_error(); + warn!( "Couldn't chown '{}' to {}: {}", output_path, uid, err ); + } else { + info!( "File '{}' was chown'd to {}", output_path, uid ); + } + } + + Some( (fp, output_path.into()) ) +} + +pub struct BacktraceCache { + next_id: u64, + cache: lru::LruCache< u64, Backtrace, NoHash > +} + +impl BacktraceCache { + pub fn new( cache_size: usize ) -> Self { + BacktraceCache { + next_id: 1, + cache: lru::LruCache::with_hasher( cache_size, NoHash ) + } + } + + pub(crate) fn assign_id( &mut self, backtrace: &Backtrace ) -> (u64, bool) { + let key = backtrace.key(); + if let Some( id ) = backtrace.id() { + self.cache.get( &key ); + return (id, false); + } + + match self.cache.get_mut( &key ) { + None => { + if cfg!( debug_assertions ) { + if self.cache.len() >= self.cache.cap() { + debug!( "2nd level backtrace cache overflow" ); + } + } + + let id = self.next_id; + self.next_id += 1; + backtrace.set_id( id ); + + self.cache.put( key, backtrace.clone() ); + (id, true) + }, + Some( cached_backtrace ) => { + if Backtrace::ptr_eq( &cached_backtrace, &backtrace ) || cached_backtrace.frames() == backtrace.frames() { + (cached_backtrace.id().expect( "internal error: id was not set on a cached backtrace" ), false) + } else { + info!( "2nd level backtrace cache conflict detected!" ); + + let id = self.next_id; + self.next_id += 1; + backtrace.set_id( id ); + + *cached_backtrace = backtrace.clone(); + + (id, true) + } + } + } + } +} + +fn emit_allocation_bucket( mut bucket: AllocationBucket, backtrace_cache: &mut BacktraceCache, fp: &mut impl Write ) -> Result< (), std::io::Error > { + if bucket.events.len() == 0 { + return Ok(()); + } + + let mut iter = bucket.events.drain( .. ); + + let BufferedAllocation { timestamp, allocation, backtrace } = iter.next().unwrap(); + let mut old_pointer = allocation.address; + let backtrace = writers::write_backtrace( &mut *fp, backtrace, backtrace_cache )?; + Event::AllocEx { + id: bucket.id, + timestamp, + allocation: common::event::AllocBody { + pointer: allocation.address.get() as u64, + size: allocation.size as u64, + backtrace, + thread: allocation.tid, + flags: allocation.flags, + extra_usable_space: 0, + preceding_free_space: 0 + } + }.write_to_stream( &mut *fp )?; + + while let Some( BufferedAllocation { timestamp, allocation, backtrace } ) = iter.next() { + let backtrace = writers::write_backtrace( &mut *fp, backtrace, backtrace_cache )?; + + Event::ReallocEx { + id: bucket.id, + timestamp, + old_pointer: old_pointer.get() as u64, + allocation: common::event::AllocBody { + pointer: allocation.address.get() as u64, + size: allocation.size as u64, + backtrace, + thread: allocation.tid, + flags: allocation.flags, + extra_usable_space: 0, + preceding_free_space: 0 + } + }.write_to_stream( &mut *fp )?; + old_pointer = allocation.address; + } + + Ok(()) +} + +pub(crate) fn thread_main() { + info!( "Starting event thread..." ); + + let uuid = generate_data_id(); + let initial_timestamp = get_timestamp(); + info!( "Data ID: {}", uuid ); + + let mut output_writer = Lz4Writer::new( Output::new() ); + if let Some( (fp, path) ) = initialize_output_file() { + let mut fp = Lz4Writer::new( fp ); + match writers::write_initial_data( uuid, initial_timestamp, &mut fp ) { + Ok(()) => { + let fp = fp.into_inner().unwrap(); + + let mut output = Output::new(); + output.set_file( fp, path ); + output_writer.replace_inner( output ).unwrap(); + }, + Err( error ) => { + warn!( "Failed to write initial data: {}", error ); + } + } + } + + let mut listener = None; + + if opt::get().enable_server { + if let Some( listener_instance ) = create_listener() { + let listener_port = listener_instance.local_addr().expect( "couldn't grab the local address of the listener" ).port(); + listener = Some( (listener_instance, listener_port) ); + } + } + + let mut events = Vec::new(); + let mut last_flush_timestamp = get_timestamp(); + let mut coarse_timestamp = get_timestamp(); + let mut running = true; + let mut allocation_lock_for_memory_dump = None; + let mut last_broadcast = coarse_timestamp; + let mut last_server_poll = coarse_timestamp; + let mut timestamp_override = None; + let mut poll_fds = Vec::new(); + let mut backtrace_cache = BacktraceCache::new( opt::get().backtrace_cache_size_level_2 ); + let mut thread_gc = crate::global::ThreadGarbageCollector::default(); + loop { + timed_recv_all_events( &mut events, Duration::from_millis( 250 ) ); + + crate::global::try_disable_if_requested(); + coarse_timestamp = get_timestamp(); + if let Some( (ref mut listener, listener_port) ) = listener { + if (coarse_timestamp - last_broadcast).as_secs() >= 1 { + last_broadcast = coarse_timestamp; + if opt::get().enable_broadcasts { + let _ = send_broadcast( uuid, initial_timestamp, listener_port ); + } + } + + if (coarse_timestamp - last_server_poll).as_msecs() >= 250 { + last_server_poll = coarse_timestamp; + match listener.accept() { + Ok( (stream, _) ) => { + match Client::new( uuid, initial_timestamp, listener_port, stream ) { + Ok( client ) => { + output_writer.inner_mut_without_flush().clients.push( client ); + }, + Err( error ) => { + info!( "Failed to initialize client: {}", error ); + } + } + }, + Err( ref error ) if error.kind() == io::ErrorKind::WouldBlock => {}, + Err( _ ) => {} + } + + poll_clients( uuid, initial_timestamp, &mut poll_fds, &mut output_writer ); + } + } + + thread_gc.run( coarse_timestamp, &mut events ); + crate::allocation_tracker::on_tick(); + + if events.is_empty() && !running { + break; + } + + if events.is_empty() { + if let Some( _lock ) = allocation_lock_for_memory_dump.take() { + if !output_writer.inner().is_none() { + let _ = writer_memory::write_memory_dump( &mut output_writer ); + } + } + } + + let serializer = &mut output_writer; + let skip = serializer.inner().is_none(); + for event in events.drain(..) { + match event { + InternalEvent::Alloc { + id, + mut timestamp, + allocation, + backtrace + } => { + if skip { + continue; + } + + if timestamp == Timestamp::min() { + timestamp = coarse_timestamp; + } + + timestamp = timestamp_override.take().unwrap_or( timestamp ); + + if let Ok( backtrace ) = writers::write_backtrace( &mut *serializer, backtrace, &mut backtrace_cache ) { + let _ = Event::AllocEx { + id, + timestamp, + allocation: common::event::AllocBody { + pointer: allocation.address.get() as u64, + size: allocation.size as u64, + backtrace, + thread: allocation.tid, + flags: allocation.flags, + extra_usable_space: allocation.extra_usable_space, + preceding_free_space: allocation.preceding_free_space + } + }.write_to_stream( &mut *serializer ); + } + }, + InternalEvent::Realloc { + id, + mut timestamp, + old_address, + allocation, + backtrace, + } => { + if skip { + continue; + } + + if timestamp == Timestamp::min() { + timestamp = coarse_timestamp; + } + + timestamp = timestamp_override.take().unwrap_or( timestamp ); + + if let Ok( backtrace ) = writers::write_backtrace( &mut *serializer, backtrace, &mut backtrace_cache ) { + let event = Event::ReallocEx { + id, + timestamp, + old_pointer: old_address.get() as u64, + allocation: common::event::AllocBody { + pointer: allocation.address.get() as u64, + size: allocation.size as u64, + backtrace, + thread: allocation.tid, + flags: allocation.flags, + extra_usable_space: allocation.extra_usable_space, + preceding_free_space: allocation.preceding_free_space + } + }; + let _ = event.write_to_stream( &mut *serializer ); + } + }, + InternalEvent::Free { + id, + address, + backtrace, + mut timestamp, + tid + } => { + if skip { + continue; + } + + if timestamp == Timestamp::min() { + timestamp = coarse_timestamp; + } + + timestamp = timestamp_override.take().unwrap_or( timestamp ); + + let backtrace = + if let Some( backtrace ) = backtrace { + writers::write_backtrace( &mut *serializer, backtrace, &mut backtrace_cache ).ok() + } else { + Some( 0 ) + }; + + if let Some( backtrace ) = backtrace { + let _ = Event::FreeEx { + id: id.into(), + timestamp, + pointer: address.get() as u64, + backtrace, + thread: tid + }.write_to_stream( &mut *serializer ); + } + }, + InternalEvent::AllocationBucket( bucket ) => { + if skip { + continue; + } + + let _ = emit_allocation_bucket( bucket, &mut backtrace_cache, &mut *serializer ); + }, + InternalEvent::Mmap { pointer, length, backtrace, requested_address, mmap_protection, mmap_flags, file_descriptor, offset, mut timestamp, thread } => { + let system_tid = thread.system_tid(); + mem::drop( thread ); + + if skip { + continue; + } + + if timestamp == Timestamp::min() { + timestamp = coarse_timestamp; + } + + timestamp = timestamp_override.take().unwrap_or( timestamp ); + + if let Ok( backtrace ) = writers::write_backtrace( &mut *serializer, backtrace, &mut backtrace_cache ) { + let event = Event::MemoryMap { + timestamp, + pointer: pointer as u64, + length: length as u64, + backtrace, + thread: system_tid, + requested_address: requested_address as u64, + mmap_protection, + mmap_flags, + file_descriptor, + offset + }; + + let _ = event.write_to_stream( &mut *serializer ); + } + }, + InternalEvent::Munmap { ptr, len, backtrace, mut timestamp, thread } => { + let system_tid = thread.system_tid(); + mem::drop( thread ); + + if skip { + continue; + } + + if timestamp == Timestamp::min() { + timestamp = coarse_timestamp; + } + + let timestamp = timestamp_override.take().unwrap_or( timestamp ); + + if let Ok( backtrace ) = writers::write_backtrace( &mut *serializer, backtrace, &mut backtrace_cache ) { + let event = Event::MemoryUnmap { timestamp, pointer: ptr as u64, length: len as u64, backtrace, thread: system_tid }; + let _ = event.write_to_stream( &mut *serializer ); + } + }, + InternalEvent::Mallopt { param, value, result, mut timestamp, backtrace, thread } => { + let system_tid = thread.system_tid(); + mem::drop( thread ); + + if skip { + continue; + } + + if timestamp == Timestamp::min() { + timestamp = coarse_timestamp; + } + + let timestamp = timestamp_override.take().unwrap_or( timestamp ); + + if let Ok( backtrace ) = writers::write_backtrace( &mut *serializer, backtrace, &mut backtrace_cache ) { + let event = Event::Mallopt { timestamp, param, value, result, backtrace, thread: system_tid }; + let _ = event.write_to_stream( &mut *serializer ); + } + }, + InternalEvent::Exit => { + crate::allocation_tracker::on_exit(); + running = false; + }, + InternalEvent::GrabMemoryDump => { + // Block any further allocations. + if allocation_lock_for_memory_dump.is_none() { + debug!( "Locking allocations to prepare for a memory dump" ); + allocation_lock_for_memory_dump = Some( AllocationLock::new() ); + } + }, + InternalEvent::SetMarker { value } => { + if skip { + continue; + } + + let event = Event::Marker { value }; + let _ = event.write_to_stream( &mut *serializer ); + }, + InternalEvent::OverrideNextTimestamp { timestamp } => { + timestamp_override = Some( timestamp ); + }, + InternalEvent::AddressSpaceUpdated { maps, new_binaries } => { + let timestamp = get_timestamp(); + if opt::get().write_binaries_to_output || serializer.inner_mut_without_flush().file.is_none() { + for binary in new_binaries { + debug!( "Writing new binary: {}", binary.name() ); + let event = Event::File64 { + timestamp, + path: binary.name().into(), + contents: binary.as_bytes().into() + }; + + let _ = event.write_to_stream( &mut *serializer ); + } + } + + debug!( "Writing new maps..." ); + let event = Event::File64 { + timestamp, + path: "/proc/self/maps".into(), + contents: maps.as_bytes().into() + }; + + let _ = event.write_to_stream( &mut *serializer ); + } + } + } + + if (coarse_timestamp - last_flush_timestamp).as_secs() > 30 { + last_flush_timestamp = get_timestamp(); + let _ = serializer.flush(); + } + } + + let _ = output_writer.flush(); + for client in &mut output_writer.inner_mut_without_flush().clients { + let _ = Response::Finished.write_to_stream( &mut client.stream ); + let _ = client.stream.flush(); + } + + info!( "Event thread finished" ); +} diff --git a/preload-syscaller/src/raw_file.rs b/preload-syscaller/src/raw_file.rs new file mode 100644 index 00000000..f5a3fd0c --- /dev/null +++ b/preload-syscaller/src/raw_file.rs @@ -0,0 +1,122 @@ +use std::path::Path; +use std::io::{self, Write}; +use std::ffi::CStr; +use std::os::unix::io::{IntoRawFd, FromRawFd, AsRawFd, RawFd}; +use std::mem; +use libc; + +use crate::syscall; +use crate::utils::stack_null_terminate; + +#[repr(transparent)] +pub struct RawFile { + fd: libc::c_int +} + +impl RawFile { + pub fn borrow_raw( fd: &libc::c_int ) -> &RawFile { + unsafe { &*(fd as *const libc::c_int as *const RawFile) } + } + + pub fn create< P: AsRef< Path > >( path: P, permissions: libc::c_int ) -> Result< Self, io::Error > { + let path = path.as_ref(); + + let fd = stack_null_terminate( path.to_str().unwrap().as_bytes(), |path| { + let path = CStr::from_bytes_with_nul( path ).unwrap(); + syscall::open( path, libc::O_CLOEXEC | libc::O_CREAT | libc::O_TRUNC | libc::O_WRONLY, permissions ) + }); + + if fd < 0 { + return Err( io::Error::from_raw_os_error( fd ) ); + } + + let fp = RawFile { + fd + }; + + Ok( fp ) + } + + pub fn chmod( &self, permissions: libc::mode_t ) { + syscall::fchmod( self.fd, permissions ); + } +} + +impl Drop for RawFile { + #[inline] + fn drop( &mut self ) { + syscall::close( self.fd ); + } +} + +impl AsRawFd for RawFile { + #[inline] + fn as_raw_fd( &self ) -> RawFd { + self.fd + } +} + +impl IntoRawFd for RawFile { + #[inline] + fn into_raw_fd( self ) -> RawFd { + let fd = self.fd; + mem::forget( self ); + + fd + } +} + +impl FromRawFd for RawFile { + #[inline] + unsafe fn from_raw_fd( fd: RawFd ) -> Self { + RawFile { fd } + } +} + +impl Write for RawFile { + #[inline] + fn write( &mut self, buffer: &[u8] ) -> Result< usize, io::Error > { + <&RawFile as Write>::write( &mut &*self, buffer ) + } + + #[inline] + fn flush( &mut self ) -> Result< (), io::Error > { + <&RawFile as Write>::flush( &mut &*self ) + } +} + +impl< 'a > Write for &'a RawFile { + #[inline] + fn write( &mut self, buffer: &[u8] ) -> Result< usize, io::Error > { + let count = syscall::write( self.fd, buffer ); + if count < 0 { + Err( io::Error::from_raw_os_error( count as _ ) ) + } else { + Ok( count as _ ) + } + } + + #[inline] + fn flush( &mut self ) -> Result< (), io::Error > { + Ok(()) + } +} + +pub fn rename< S: AsRef< Path >, D: AsRef< Path > >( src: S, dst: D ) -> Result< (), io::Error > { + let src = src.as_ref(); + let dst = dst.as_ref(); + + let errcode = stack_null_terminate( src.to_str().unwrap().as_bytes(), |src| { + let src = CStr::from_bytes_with_nul( src ).unwrap(); + stack_null_terminate( dst.to_str().unwrap().as_bytes(), |dst| { + let dst = CStr::from_bytes_with_nul( dst ).unwrap(); + syscall::rename( src, dst ) + }) + }); + + if errcode == 0 { + Ok(()) + } else { + Err( io::Error::from_raw_os_error( errcode as _ ) ) + } +} diff --git a/preload-syscaller/src/spin_lock.rs b/preload-syscaller/src/spin_lock.rs new file mode 100644 index 00000000..bc84229f --- /dev/null +++ b/preload-syscaller/src/spin_lock.rs @@ -0,0 +1,84 @@ +use std::sync::atomic::{AtomicBool, Ordering}; +use std::ops::{Deref, DerefMut}; +use std::cell::UnsafeCell; +use std::mem::transmute; + +pub struct SpinLock< T > { + pub value: UnsafeCell< T >, + pub flag: AtomicBool +} + +unsafe impl< T > Send for SpinLock< T > where T: Send {} +unsafe impl< T > Sync for SpinLock< T > where T: Send {} + +pub struct SpinLockGuard< 'a, T: 'a >( &'a SpinLock< T > ); + +impl< T > SpinLock< T > { + pub const fn new( value: T ) -> Self { + SpinLock { + value: UnsafeCell::new( value ), + flag: AtomicBool::new( false ) + } + } + + pub fn lock( &self ) -> SpinLockGuard< T > { + while self.flag.compare_exchange_weak( false, true, Ordering::Acquire, Ordering::Acquire ).is_err() { + } + + SpinLockGuard( self ) + } + + pub fn try_lock( &self ) -> Option< SpinLockGuard< T > > { + if self.flag.compare_exchange( false, true, Ordering::Acquire, Ordering::Acquire ).is_ok() { + Some( SpinLockGuard( self ) ) + } else { + None + } + } + + pub unsafe fn unsafe_as_ref( &self ) -> &T { + &*self.value.get() + } + + pub unsafe fn force_unlock( &self ) { + self.flag.store( false, Ordering::SeqCst ); + } +} + +impl< 'a, T > SpinLockGuard< 'a, T > { + #[allow(dead_code)] + pub fn unwrap( self ) -> Self { + self + } +} + +impl< 'a, T > SpinLockGuard< 'a, *mut T > { + #[allow(dead_code)] + pub unsafe fn as_ref( self ) -> SpinLockGuard< 'a, &'a T > { + transmute( self ) + } +} + +impl< 'a, T > Drop for SpinLockGuard< 'a, T > { + fn drop( &mut self ) { + self.0.flag.store( false, Ordering::Release ); + } +} + +impl< 'a, T > Deref for SpinLockGuard< 'a, T > { + type Target = T; + + fn deref( &self ) -> &Self::Target { + unsafe { + &*self.0.value.get() + } + } +} + +impl< 'a, T > DerefMut for SpinLockGuard< 'a, T > { + fn deref_mut( &mut self ) -> &mut Self::Target { + unsafe { + &mut *self.0.value.get() + } + } +} diff --git a/preload-syscaller/src/syscall.rs b/preload-syscaller/src/syscall.rs new file mode 100644 index 00000000..eadfcbb5 --- /dev/null +++ b/preload-syscaller/src/syscall.rs @@ -0,0 +1,157 @@ +use std::ffi::CStr; +use libc; +use crate::utils::Buffer; + +#[cfg(not(feature = "sc"))] +macro_rules! syscall { + (@to_libc OPEN) => { libc::SYS_open }; + (@to_libc OPENAT) => { libc::SYS_openat }; + (@to_libc CLOSE) => { libc::SYS_close }; + (@to_libc WRITE) => { libc::SYS_write }; + (@to_libc UMASK) => { libc::SYS_umask }; + (@to_libc FCHMOD) => { libc::SYS_fchmod }; + (@to_libc RENAME) => { libc::SYS_rename }; + (@to_libc RENAMEAT) => { libc::SYS_renameat }; + (@to_libc GETTID) => { libc::SYS_gettid }; + (@to_libc EXIT) => { libc::SYS_exit }; + (@to_libc MMAP) => { libc::SYS_mmap }; + (@to_libc MMAP2) => { libc::SYS_mmap2 }; + (@to_libc MUNMAP) => { libc::SYS_munmap }; + (@to_libc GETPID) => { libc::SYS_getpid }; + + ($num:ident) => { + libc::syscall( syscall!( @to_libc $num ) ) + }; + + ($num:ident, $($args:expr),+) => { + libc::syscall( syscall!( @to_libc $num ), $($args),+ ) + }; +} + +pub fn open( path: &CStr, flags: libc::c_int, mode: libc::c_int ) -> libc::c_int { + open_raw_cstr( path.as_ptr(), flags, mode ) +} + +pub fn open_raw_cstr( path: *const libc::c_char, flags: libc::c_int, mode: libc::c_int ) -> libc::c_int { + #[cfg(not(target_arch = "aarch64"))] + unsafe { + syscall!( OPEN, path, flags, mode ) as _ + } + + #[cfg(target_arch = "aarch64")] + unsafe { + syscall!( OPENAT, libc::AT_FDCWD, path, flags, mode ) as _ + } +} + +pub fn close( fd: libc::c_int ) -> libc::c_int { + unsafe { + syscall!( CLOSE, fd ) as _ + } +} + +pub fn write( fd: libc::c_int, buffer: &[u8] ) -> libc::ssize_t { + unsafe { + syscall!( WRITE, fd, buffer.as_ptr(), buffer.len() ) as _ + } +} + +pub fn umask( umask: libc::c_int ) -> libc::c_int { + unsafe { + syscall!( UMASK, umask ) as _ + } +} + +pub fn fchmod( fd: libc::c_int, mode: libc::mode_t ) -> libc::c_int { + unsafe { + syscall!( FCHMOD, fd, mode ) as _ + } +} + +pub fn rename( source: &CStr, destination: &CStr ) -> libc::c_int { + let source = source.as_ptr(); + let destination = destination.as_ptr(); + + #[cfg(not(target_arch = "aarch64"))] + unsafe { + syscall!( RENAME, source, destination ) as _ + } + + #[cfg(target_arch = "aarch64")] + unsafe { + syscall!( RENAMEAT, libc::AT_FDCWD, source, libc::AT_FDCWD, destination ) as _ + } +} + +pub fn getpid() -> libc::pid_t { + unsafe { + syscall!( GETPID ) as libc::pid_t + } +} + +pub fn gettid() -> u32 { + unsafe { + syscall!( GETTID ) as u32 + } +} + +pub fn exit( status: u32 ) -> ! { + unsafe { + syscall!( EXIT, status ); + core::hint::unreachable_unchecked(); + } +} + +#[cfg(target_arch = "arm")] +pub unsafe fn mmap( addr: *mut libc::c_void, length: libc::size_t, prot: libc::c_int, flags: libc::c_int, fildes: libc::c_int, off: libc::off_t ) -> *mut libc::c_void { + syscall!( MMAP2, addr, length, prot, flags, fildes, off / (crate::PAGE_SIZE as libc::off_t) ) as *mut libc::c_void +} + +#[cfg(not(target_arch = "arm"))] +pub unsafe fn mmap( addr: *mut libc::c_void, length: libc::size_t, prot: libc::c_int, flags: libc::c_int, fildes: libc::c_int, off: libc::off_t ) -> *mut libc::c_void { + syscall!( MMAP, addr, length, prot, flags, fildes, off ) as *mut libc::c_void +} + +pub unsafe fn munmap( addr: *mut libc::c_void, length: libc::size_t ) -> libc::c_int { + syscall!( MUNMAP, addr, length ) as libc::c_int +} + +extern "C" { + static __environ: *const *const u8; +} + +pub unsafe fn getenv( key: &[u8] ) -> Option< Buffer > { + let mut current = __environ; + loop { + let p = *current; + if p.is_null() { + return None; + } + + let mut r = p; + while *r != b'=' { + r = r.add( 1 ); + } + + let entry_key_length = r as usize - p as usize; + let entry_key = std::slice::from_raw_parts( p, entry_key_length ); + if key == entry_key { + r = r.add( 1 ); + let value_pointer = r; + while *r != 0 { + r = r.add( 1 ); + } + + let value_length = r as usize - value_pointer as usize; + return Buffer::from_slice( std::slice::from_raw_parts( value_pointer, value_length ) ); + } + + current = current.add( 1 ); + } +} + +#[test] +fn test_getenv() { + std::env::set_var( "GETENV_TEST_VAR", "1234" ); + assert_eq!( unsafe { getenv( b"GETENV_TEST_VAR" ) }.unwrap().to_str().unwrap(), "1234" ); +} \ No newline at end of file diff --git a/preload-syscaller/src/timestamp.rs b/preload-syscaller/src/timestamp.rs new file mode 100644 index 00000000..cef800af --- /dev/null +++ b/preload-syscaller/src/timestamp.rs @@ -0,0 +1,30 @@ +use libc; + +pub use common::Timestamp; + +pub fn get_timestamp() -> Timestamp { + let mut timespec = libc::timespec { + tv_sec: 0, + tv_nsec: 0 + }; + + unsafe { + libc::clock_gettime( libc::CLOCK_MONOTONIC, &mut timespec ); + } + + Timestamp::from_timespec( timespec.tv_sec as u64, timespec.tv_nsec as u64 ) +} + +pub fn get_wall_clock() -> (Timestamp, u64, u64) { + let timestamp = get_timestamp(); + let mut timespec = libc::timespec { + tv_sec: 0, + tv_nsec: 0 + }; + + unsafe { + libc::clock_gettime( libc::CLOCK_REALTIME, &mut timespec ); + } + + (timestamp, timespec.tv_sec as u64, timespec.tv_nsec as u64) +} diff --git a/preload-syscaller/src/unwind.rs b/preload-syscaller/src/unwind.rs new file mode 100644 index 00000000..0c535040 --- /dev/null +++ b/preload-syscaller/src/unwind.rs @@ -0,0 +1,461 @@ +use std::mem::{self, transmute}; +use std::sync::atomic::{AtomicU64, AtomicUsize}; +use libc::{self, c_void, c_int, uintptr_t}; +use perf_event_open::{Perf, EventSource, Event}; +use nwind::{ + LocalAddressSpace, + LocalAddressSpaceOptions, + LocalUnwindContext, + UnwindControl +}; +use std::sync::{RwLock, RwLockReadGuard}; + +use crate::global::StrongThreadHandle; +use crate::spin_lock::SpinLock; +use crate::opt; +use crate::nohash::NoHash; + +#[repr(C)] +pub struct BacktraceHeader { + pub key: u64, + pub id: AtomicU64, + counter: AtomicUsize, + length: usize +} + +pub struct Backtrace( std::ptr::NonNull< BacktraceHeader > ); +unsafe impl Send for Backtrace {} +unsafe impl Sync for Backtrace {} + +impl Backtrace { + pub fn ptr_eq( lhs: &Backtrace, rhs: &Backtrace ) -> bool { + lhs.0.as_ptr() == rhs.0.as_ptr() + } + + pub fn key( &self ) -> u64 { + self.header().key + } + + pub fn id( &self ) -> Option< u64 > { + let id = self.header().id.load( std::sync::atomic::Ordering::Relaxed ); + if id == 0 { + None + } else { + Some( id ) + } + } + + pub fn set_id( &self, value: u64 ) { + self.header().id.store( value, std::sync::atomic::Ordering::Relaxed ); + } + + pub fn frames( &self ) -> &[usize] { + let length = self.header().length; + unsafe { + let ptr = (self.0.as_ptr() as *const BacktraceHeader as *const u8).add( std::mem::size_of::< BacktraceHeader >() ) as *const usize; + std::slice::from_raw_parts( ptr, length ) + } + } +} + +impl Clone for Backtrace { + #[inline] + fn clone( &self ) -> Self { + self.header().counter.fetch_add( 1, std::sync::atomic::Ordering::Relaxed ); + Backtrace( self.0.clone() ) + } +} + +impl Drop for Backtrace { + #[inline] + fn drop( &mut self ) { + unsafe { + if self.header().counter.fetch_sub( 1, std::sync::atomic::Ordering::Release ) != 1 { + return; + } + + std::sync::atomic::fence( std::sync::atomic::Ordering::Acquire ); + self.drop_slow(); + } + } +} + +impl Backtrace { + fn new( key: u64, backtrace: &[usize] ) -> Self { + unsafe { + let length = backtrace.len(); + let layout = std::alloc::Layout::from_size_align( std::mem::size_of::< BacktraceHeader >() + std::mem::size_of::< usize >() * length, 8 ).unwrap(); + let memory = std::alloc::alloc( layout ) as *mut BacktraceHeader; + std::ptr::write( memory, BacktraceHeader { + key, + id: AtomicU64::new( 0 ), + counter: AtomicUsize::new( 1 ), + length + }); + std::ptr::copy_nonoverlapping( + backtrace.as_ptr(), + (memory as *mut u8).add( std::mem::size_of::< BacktraceHeader >() ) as *mut usize, + length + ); + + Backtrace( std::ptr::NonNull::new_unchecked( memory ) ) + } + } + + #[inline(never)] + unsafe fn drop_slow( &mut self ) { + let length = self.header().length; + let layout = std::alloc::Layout::from_size_align( std::mem::size_of::< BacktraceHeader >() + std::mem::size_of::< usize >() * length, 8 ).unwrap(); + std::alloc::dealloc( self.0.as_ptr() as *mut u8, layout ); + } + + #[inline] + fn header( &self ) -> &BacktraceHeader { + unsafe { + self.0.as_ref() + } + } +} + +pub struct ThreadUnwindState { + unwind_ctx: LocalUnwindContext, + last_dl_state: (u64, u64), + current_backtrace: Vec< usize >, + buffer: Vec< usize >, + cache: lru::LruCache< u64, Backtrace, NoHash > +} + +impl ThreadUnwindState { + pub fn new() -> Self { + ThreadUnwindState { + unwind_ctx: LocalUnwindContext::new(), + last_dl_state: (0, 0), + current_backtrace: Vec::new(), + buffer: Vec::new(), + cache: lru::LruCache::with_hasher( crate::opt::get().backtrace_cache_size_level_1, NoHash ) + } + } +} + +type Context = *mut c_void; +type ReasonCode = c_int; +type Callback = extern "C" fn( Context, *mut c_void ) -> ReasonCode; + +extern "C" { + fn _Unwind_Backtrace( callback: Callback, data: *mut c_void ) -> ReasonCode; + fn _Unwind_GetIP( context: Context ) -> uintptr_t; + fn _Unwind_VRS_Get( context: Context, regclass: _Unwind_VRS_RegClass, regno: u32, repr: _Unwind_VRS_DataRepresentation, valuep: *mut c_void ) -> _Unwind_VRS_Result; +} + +#[allow(non_camel_case_types)] +#[repr(C)] +enum _Unwind_VRS_RegClass { + _UVRSC_CORE = 0, + _UVRSC_VFP = 1, + _UVRSC_WMMXD = 3, + _UVRSC_WMMXC = 4 +} + +#[allow(non_camel_case_types)] +#[repr(C)] +enum _Unwind_VRS_DataRepresentation { + _UVRSD_UINT32 = 0, + _UVRSD_VFPX = 1, + _UVRSD_UINT64 = 3, + _UVRSD_FLOAT = 4, + _UVRSD_DOUBLE = 5 +} + +#[allow(non_camel_case_types)] +#[repr(C)] +enum _Unwind_VRS_Result { + _UVRSR_OK = 0, + _UVRSR_NOT_IMPLEMENTED = 1, + _UVRSR_FAILED = 2 +} + +#[cfg(not(target_arch = "arm"))] +unsafe fn get_ip( context: Context ) -> uintptr_t { + _Unwind_GetIP( context ) +} + +#[cfg(target_arch = "arm")] +unsafe fn get_gr( context: Context, index: c_int ) -> uintptr_t { + let mut value: uintptr_t = 0; + _Unwind_VRS_Get( context, _Unwind_VRS_RegClass::_UVRSC_CORE, index as u32, _Unwind_VRS_DataRepresentation::_UVRSD_UINT32, &mut value as *mut uintptr_t as *mut c_void ); + value +} + +#[cfg(target_arch = "arm")] +unsafe fn get_ip( context: Context ) -> uintptr_t { + get_gr( context, 15 ) & ( !(0x1 as uintptr_t) ) +} + +extern "C" fn on_backtrace( context: Context, data: *mut c_void ) -> ReasonCode { + unsafe { + let out: &mut Vec< usize > = transmute( data ); + out.push( get_ip( context ) as usize ); + } + + 0 +} + +lazy_static! { + static ref AS: RwLock< LocalAddressSpace > = { + let opts = LocalAddressSpaceOptions::new() + .should_load_symbols( cfg!( feature = "debug-logs" ) && log_enabled!( ::log::Level::Debug ) ); + + let mut address_space = LocalAddressSpace::new_with_opts( opts ).unwrap(); + address_space.use_shadow_stack( opt::get().enable_shadow_stack ); + RwLock::new( address_space ) + }; +} + +pub unsafe fn register_frame_by_pointer( fde: *const u8 ) { + AS.write().unwrap().register_fde_from_pointer( fde ) +} + +pub fn deregister_frame_by_pointer( fde: *const u8 ) { + AS.write().unwrap().unregister_fde_from_pointer( fde ) +} + +static mut PERF: Option< SpinLock< Perf > > = None; + +pub fn prepare_to_start_unwinding() { + static FLAG: SpinLock< bool > = SpinLock::new( false ); + let mut flag = FLAG.lock(); + if *flag { + return; + } + *flag = true; + + if !opt::get().use_perf_event_open { + return; + } + + if unsafe { PERF.is_some() } { + return; + } + + let perf = Perf::build() + .any_cpu() + .event_source( EventSource::SwDummy ) + .open(); + + match perf { + Ok( perf ) => { + unsafe { + PERF = Some( SpinLock::new( perf ) ); + } + }, + Err( error ) => { + warn!( "Failed to initialize perf_event_open: {}", error ); + } + } +} + +fn reload() { + let mut address_space = AS.write().unwrap(); + info!( "Reloading address space" ); + let update = address_space.reload().unwrap(); + crate::event::send_event( crate::event::InternalEvent::AddressSpaceUpdated { + maps: update.maps, + new_binaries: update.new_binaries + }); +} + +fn reload_if_necessary_perf_event_open( perf: &SpinLock< Perf > ) -> RwLockReadGuard< 'static, LocalAddressSpace > { + if unsafe { perf.unsafe_as_ref().are_events_pending() } { + let mut perf = perf.lock(); + let mut reload_address_space = false; + for event in perf.iter() { + match event.get() { + Event::Mmap2( ref event ) if event.filename != b"//anon" && event.inode != 0 && event.protection & libc::PROT_EXEC as u32 != 0 => { + debug!( "New executable region mmaped: {:?}", event ); + reload_address_space = true; + }, + Event::Lost( _ ) => { + debug!( "Lost events; forcing a reload" ); + reload_address_space = true; + }, + _ => {} + } + } + + if reload_address_space { + reload(); + } + } + + AS.read().unwrap() +} + +fn reload_if_necessary_dl_iterate_phdr( last_state: &mut (u64, u64) ) -> RwLockReadGuard< 'static, LocalAddressSpace > { + let dl_state = get_dl_state(); + if *last_state != dl_state { + *last_state = dl_state; + reload(); + } + + AS.read().unwrap() +} + +fn get_dl_state() -> (u64, u64) { + unsafe extern fn callback( info: *mut libc::dl_phdr_info, _: libc::size_t, data: *mut libc::c_void ) -> libc::c_int { + let out = &mut *(data as *mut (u64, u64)); + out.0 = (*info).dlpi_adds; + out.1 = (*info).dlpi_subs; + 1 + } + + unsafe { + let mut out: (u64, u64) = (0, 0); + libc::dl_iterate_phdr( Some( callback ), &mut out as *mut _ as *mut libc::c_void ); + out + } +} + +#[inline(never)] +#[cold] +fn on_broken_unwinding( last_backtrace_depth: usize, stale_frame_count: usize ) { + error!( + "Unwinding is totally broken; last backtrace was {} frames long, and yet we've apparently popped {} frames since last unwind", + last_backtrace_depth, + stale_frame_count + ); + + unsafe { libc::abort(); } +} + +#[inline(never)] +pub fn grab( tls: &mut StrongThreadHandle ) -> Backtrace { + let unwind_state = tls.unwind_state(); + let unwind_ctx = &mut unwind_state.unwind_ctx; + + let address_space = unsafe { + if let Some( ref perf ) = PERF { + reload_if_necessary_perf_event_open( perf ) + } else { + reload_if_necessary_dl_iterate_phdr( &mut unwind_state.last_dl_state ) + } + }; + + let stale_count; + let debug_crosscheck_unwind_results = opt::crosscheck_unwind_results_with_libunwind() && !address_space.is_shadow_stack_enabled(); + if debug_crosscheck_unwind_results || !opt::emit_partial_backtraces() { + stale_count = unwind_state.current_backtrace.len(); + + let buffer = &mut unwind_state.buffer; + buffer.clear(); + + address_space.unwind( unwind_ctx, |address| { + buffer.push( address ); + UnwindControl::Continue + }); + } else { + let buffer = &mut unwind_state.buffer; + buffer.clear(); + + let stale_count_opt = address_space.unwind_through_fresh_frames( unwind_ctx, |address| { + buffer.push( address ); + UnwindControl::Continue + }); + + let last_backtrace_depth = unwind_state.current_backtrace.len(); + let mut new_backtrace_depth = buffer.len(); + + if let Some( stale_frame_count ) = stale_count_opt { + if stale_frame_count > last_backtrace_depth { + on_broken_unwinding( last_backtrace_depth, stale_frame_count ); + } else { + new_backtrace_depth += last_backtrace_depth - stale_frame_count; + if cfg!( feature = "debug-logs" ) { + debug!( "Finished unwinding; backtrace depth: {} (fresh = {}, non-fresh = {})", new_backtrace_depth, buffer.len(), last_backtrace_depth - stale_frame_count ); + } + } + } else { + if cfg!( feature = "debug-logs" ) { + debug!( "Finished unwinding; backtrace depth: {}", new_backtrace_depth ); + } + } + + stale_count = stale_count_opt.unwrap_or( unwind_state.current_backtrace.len() ); + } + + mem::drop( address_space ); + + let remaining = unwind_state.current_backtrace.len() - stale_count; + unwind_state.current_backtrace.truncate( remaining ); + unwind_state.current_backtrace.reserve( unwind_state.buffer.len() ); + + const PRIME: u64 = 1099511628211; + let mut key: u64 = 0; + for &frame in &unwind_state.current_backtrace { + key = key.wrapping_mul( PRIME ); + key ^= frame as u64; + } + for &frame in unwind_state.buffer.iter().rev() { + key = key.wrapping_mul( PRIME ); + key ^= frame as u64; + unwind_state.current_backtrace.push( frame ); + } + unwind_state.buffer.clear(); + + let backtrace = match unwind_state.cache.get_mut( &key ) { + None => { + if cfg!( debug_assertions ) { + if unwind_state.cache.len() >= unwind_state.cache.cap() { + debug!( "1st level backtrace cache overflow" ); + } + } + + let entry = Backtrace::new( key, &unwind_state.current_backtrace ); + unwind_state.cache.put( key, entry.clone() ); + + entry + }, + Some( entry ) => { + if entry.frames() == unwind_state.current_backtrace { + entry.clone() + } else { + info!( "1st level backtrace cache conflict detected!" ); + + let new_entry = Backtrace::new( key, &unwind_state.current_backtrace ); + *entry = new_entry.clone(); + + new_entry + } + } + }; + + if debug_crosscheck_unwind_results { + let mut expected: Vec< usize > = Vec::with_capacity( backtrace.frames().len() ); + unsafe { + _Unwind_Backtrace( on_backtrace, transmute( &mut expected ) ); + } + + if expected.last() == Some( &0 ) { + expected.pop(); + } + + expected.reverse(); + if backtrace.frames()[ ..backtrace.frames().len() - 1 ] != expected[ ..expected.len() - 1 ] { + info!( "/proc/self/maps:\n{}", String::from_utf8_lossy( &::std::fs::read( "/proc/self/maps" ).unwrap() ).trim() ); + + let address_space = AS.read().unwrap(); + info!( "Expected: ({} frames)", expected.len() ); + for (nth, &address) in expected.iter().enumerate() { + info!( "({:02}) {:?}", nth, address_space.decode_symbol_once( address ) ); + } + + info!( "Actual: ({} frames)", backtrace.frames().len() ); + for (nth, &address) in backtrace.frames().iter().enumerate() { + info!( "({:02}) {:?}", nth, address_space.decode_symbol_once( address ) ); + } + + panic!( "Wrong backtrace; expected: {:?}, got: {:?}", expected, backtrace.frames() ); + } + } + + backtrace +} diff --git a/preload-syscaller/src/utils.rs b/preload-syscaller/src/utils.rs new file mode 100644 index 00000000..dd33628b --- /dev/null +++ b/preload-syscaller/src/utils.rs @@ -0,0 +1,241 @@ +use std::io::{self, Read, Write}; +use std::fs::File; +use std::fmt; +use std::mem::MaybeUninit; +use std::ptr; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::ffi::OsStr; +use std::path::Path; +use std::os::unix::ffi::OsStrExt; + +use crate::{EXECUTABLE, PID}; +use crate::syscall; + +pub fn read_file( path: &str ) -> io::Result< Vec< u8 > > { + let mut fp = File::open( path )?; + let mut buffer = Vec::new(); + fp.read_to_end( &mut buffer )?; + Ok( buffer ) +} + +pub fn copy< I: Read, O: Write >( mut input: I, mut output: O ) -> io::Result< () > { + let mut buffer = [0; 64 * 1024]; + loop { + let count = input.read( &mut buffer )?; + if count == 0 { + break; + } + output.write_all( &buffer[ 0..count ] )?; + } + Ok(()) +} + +pub struct RestoreFileCreationMaskOnDrop( libc::c_int ); +impl Drop for RestoreFileCreationMaskOnDrop { + fn drop( &mut self ) { + syscall::umask( self.0 ); + } +} + +pub fn temporarily_change_umask( umask: libc::c_int ) -> RestoreFileCreationMaskOnDrop { + let old_umask = syscall::umask( umask ); + RestoreFileCreationMaskOnDrop( old_umask ) +} + +const STACK_BUFFER_LEN: usize = 1024; + +pub struct Buffer { + buffer: [MaybeUninit< u8 >; STACK_BUFFER_LEN], + length: usize +} + +impl std::fmt::Debug for Buffer { + fn fmt( &self, formatter: &mut std::fmt::Formatter ) -> std::fmt::Result { + let slice = self.as_slice(); + if let Ok( string ) = std::str::from_utf8( slice ) { + formatter.write_str( string ) + } else { + self.buffer[ 0..self.length ].fmt( formatter ) + } + } +} + +impl Buffer { + pub const fn new() -> Self { + unsafe { + Self { + buffer: MaybeUninit::< [MaybeUninit< u8 >; STACK_BUFFER_LEN] >::uninit().assume_init(), + length: 0 + } + } + } + + pub const fn from_fixed_slice< const N: usize >( slice: &[u8; N] ) -> Self { + let mut buffer = Self::new(); + let mut nth = 0; + while nth < N { + buffer.buffer[ nth ] = MaybeUninit::new( slice[ nth ] ); + nth += 1; + } + buffer.length = N; + buffer + } + + pub fn from_slice( slice: &[u8] ) -> Option< Self > { + if slice.len() > STACK_BUFFER_LEN { + return None; + } + + let mut buffer = Self::new(); + buffer.write( slice ).unwrap(); + Some( buffer ) + } + + pub fn to_str( &self ) -> Option< &str > { + std::str::from_utf8( self.as_slice() ).ok() + } + + pub fn as_slice( &self ) -> &[u8] { + unsafe { std::slice::from_raw_parts( self.buffer.as_ptr() as *const u8, self.length ) } + } + + fn as_slice_mut( &mut self ) -> &mut [u8] { + unsafe { std::slice::from_raw_parts_mut( self.buffer.as_mut_ptr() as *mut u8, self.length ) } + } + + fn push( &mut self, byte: u8 ) { + if self.length >= self.buffer.len() { + return; + } + + self.buffer[ self.length ] = MaybeUninit::new( byte ); + self.length += 1; + } +} + +impl std::ops::Deref for Buffer { + type Target = [u8]; + fn deref( &self ) -> &Self::Target { + self.as_slice() + } +} + +impl AsRef< OsStr > for Buffer { + fn as_ref( &self ) -> &OsStr { + OsStr::from_bytes( self.as_slice() ) + } +} + +impl AsRef< Path > for Buffer { + fn as_ref( &self ) -> &Path { + Path::new( self ) + } +} + +impl Write for Buffer { + fn write( &mut self, input: &[u8] ) -> io::Result< usize > { + let count = std::cmp::min( input.len(), STACK_BUFFER_LEN - self.length ); + unsafe { + std::ptr::copy_nonoverlapping( input.as_ptr(), self.buffer[ self.length.. ].as_mut_ptr() as *mut u8, count ); + } + self.length += count; + Ok( count ) + } + + fn flush( &mut self ) -> io::Result< () > { + Ok(()) + } +} + +fn stack_format< R, F, G >( format_callback: F, use_callback: G ) -> R + where F: FnOnce( &mut Buffer ), + G: FnOnce( &mut [u8] ) -> R +{ + let mut buffer = Buffer::new(); + format_callback( &mut buffer ); + use_callback( buffer.as_slice_mut() ) +} + +#[test] +fn test_stack_format_short() { + stack_format( |out| { + write!( out, "foo = {}", "bar" ).unwrap(); + write!( out, ";" ).unwrap(); + }, |output| { + assert_eq!( output, b"foo = bar;" ); + }); +} + +#[test] +fn test_stack_format_long() { + stack_format( |out| { + for _ in 0..STACK_BUFFER_LEN { + write!( out, "X" ).unwrap(); + } + assert!( write!( out, "Y" ).is_err() ); + }, |output| { + assert_eq!( output.len(), STACK_BUFFER_LEN ); + assert!( output.iter().all( |&byte| byte == b'X' ) ); + }); +} + +pub fn stack_format_bytes< R, F >( args: fmt::Arguments, callback: F ) -> R + where F: FnOnce( &mut [u8] ) -> R +{ + stack_format( |out| { + let _ = out.write_fmt( args ); + }, callback ) +} + +pub fn stack_null_terminate< R, F >( input: &[u8], callback: F ) -> R + where F: FnOnce( &mut [u8] ) -> R +{ + stack_format( |out| { + let _ = out.write_all( input ); + let _ = out.write_all( &[0] ); + }, callback ) +} + +pub fn generate_filename( pattern: &[u8], counter: Option< &AtomicUsize > ) -> Buffer { + let mut output = Buffer::new(); + let mut seen_percent = false; + for &ch in pattern.as_ref() { + if !seen_percent && ch == b'%' { + seen_percent = true; + continue; + } + + if seen_percent { + seen_percent = false; + match ch { + b'%' => { + output.push( ch ); + }, + b'p' => { + let pid = *PID; + write!( &mut output, "{}", pid ).unwrap(); + }, + b't' => { + let timestamp = unsafe { libc::time( ptr::null_mut() ) }; + write!( &mut output, "{}", timestamp ).unwrap(); + }, + b'e' => { + let executable = String::from_utf8_lossy( &*EXECUTABLE ); + let executable = &executable[ executable.rfind( "/" ).map( |index| index + 1 ).unwrap_or( 0 ).. ]; + write!( &mut output, "{}", executable ).unwrap(); + }, + b'n' => { + if let Some( counter ) = counter { + let value = counter.fetch_add( 1, Ordering::SeqCst ); + write!( &mut output, "{}", value ).unwrap(); + } + }, + _ => {} + } + } else { + output.push( ch ); + } + } + + output +} diff --git a/preload-syscaller/src/writer_memory.rs b/preload-syscaller/src/writer_memory.rs new file mode 100644 index 00000000..9c400d6d --- /dev/null +++ b/preload-syscaller/src/writer_memory.rs @@ -0,0 +1,135 @@ +use std::cmp::min; +use std::fs::File; +use std::io::{self, Read, Write, Seek, SeekFrom}; +use std::ptr; + +use nwind::proc_maps::parse as parse_maps; + +use common::event::Event; +use common::speedy::Writable; + +use crate::PAGE_SIZE; +use crate::syscall; +use crate::writers::write_maps; + +fn is_accessible< U: Read + Seek >( mut fp: U, address: u64 ) -> bool { + if let Err( _ ) = fp.seek( SeekFrom::Start( address ) ) { + return false; + } + + let mut dummy: [u8; 1] = [0]; + match fp.read( &mut dummy ) { + Ok( 1 ) => true, + _ => false + } +} + +fn memory_dump_body< U: Write >( mut serializer: &mut U ) -> io::Result< () > { + let mut buffer = Vec::new(); + buffer.resize( 1024 * 128, 0 ); + let mut buffer = buffer.into_boxed_slice(); + let maps = write_maps( serializer )?; + let maps = String::from_utf8_lossy( &maps ); + let maps = parse_maps( &maps ); + let mut fp = File::open( "/proc/self/mem" )?; + let page_size = PAGE_SIZE as u64; + + + for region in maps { + if !region.is_write && region.inode != 0 { + continue; + } + + let mut end = { + let total_length = (region.end - region.start) / page_size; + + let mut start = 0; + let mut end = total_length; + loop { + if start == end { + break; + } + + let current = start + (end - start) / 2; + let accessible = is_accessible( &mut fp, region.start + current * page_size + page_size - 1 ); + if !accessible { + end = current; + } else { + start = current + 1; + } + } + + region.start + end * page_size + }; + + loop { + let chunk_size = min( buffer.len() as u64, end - region.start ); + if chunk_size == 0 { + break; + } + + let address = end - chunk_size; + fp.seek( SeekFrom::Start( address ) )?; + fp.read_exact( &mut buffer[ 0..chunk_size as usize ] )?; + let data = &buffer[ 0..chunk_size as usize ]; + Event::MemoryDump { + address, + length: chunk_size as u64, + data: data.into() + }.write_to_stream( &mut serializer )?; + + end -= chunk_size; + } + +/* + let mut page: [u8; 4096] = [0; 4096]; + while address > region.start { + fp.seek( SeekFrom::Start( address - page_size ) )?; + fp.read_exact( &mut page )?; + + if page.iter().all( |&byte| byte == 0 ) { + address -= page_size; + } else { + break; + } + } + + fp.seek( SeekFrom::Start( region.start ) )?; + let mut current = region.start; + + while current < address { + let chunk_size = min( buffer.len(), (address - current) as usize ); + fp.read_exact( &mut buffer[ 0..chunk_size ] )?; + let data = &buffer[ 0..chunk_size ]; + Event::MemoryDump { + address: current, + length: chunk_size as u64, + data + }.write_to_stream( LittleEndian, serializer )?; + current += chunk_size as u64; + } +*/ + } + + serializer.flush()?; + Ok(()) +} + +pub fn write_memory_dump< U: Write >( serializer: &mut U ) -> io::Result< () > { + info!( "Writing a memory dump..." ); + serializer.flush()?; + + let pid = unsafe { libc::fork() }; + if pid == 0 { + let result = memory_dump_body( serializer ); + syscall::exit( if result.is_err() { 1 } else { 0 } ); + } else { + info!( "Waiting for child to finish..." ); + unsafe { + libc::waitpid( pid, ptr::null_mut(), 0 ); + } + } + + info!( "Memory dump finished" ); + Ok(()) +} diff --git a/preload-syscaller/src/writers.rs b/preload-syscaller/src/writers.rs new file mode 100644 index 00000000..4075bc64 --- /dev/null +++ b/preload-syscaller/src/writers.rs @@ -0,0 +1,249 @@ +use std::collections::HashSet; +use std::ffi::CStr; +use std::fs::{self, File}; +use std::io::{self, Write}; +use std::mem; +use std::ops::Deref; +use std::path::Path; + +use nwind::proc_maps::Region; +use nwind::proc_maps::parse as parse_maps; + +use common::event::{DataId, Event, HeaderBody, HEADER_FLAG_IS_LITTLE_ENDIAN}; +use common::speedy::Writable; +use common::Timestamp; + +use crate::{CMDLINE, EXECUTABLE, PID}; +use crate::arch; +use crate::opt; +use crate::timestamp::{get_timestamp, get_wall_clock}; +use crate::utils::read_file; +use crate::processing_thread::BacktraceCache; +use crate::unwind::Backtrace; + +fn read_maps() -> io::Result< Vec< Region > > { + let maps = read_file( "/proc/self/maps" )?; + let maps_str = String::from_utf8_lossy( &maps ); + let regions = parse_maps( &maps_str ); + Ok( regions ) +} + +fn mmap_file< P: AsRef< Path >, R, F: FnOnce( &[u8] ) -> R >( path: P, callback: F ) -> io::Result< R > { + let fp = File::open( &path )?; + let mmap = unsafe { memmap::Mmap::map( &fp ) }?; + let slice = mmap.deref(); + Ok( callback( slice ) ) +} + +fn write_file< U: Write >( mut serializer: &mut U, path: &str, bytes: &[u8] ) -> io::Result< () > { + Event::File64 { + timestamp: get_timestamp(), + path: path.into(), + contents: bytes.into() + }.write_to_stream( &mut serializer )?; + + Ok(()) +} + +fn new_header_body( id: DataId, initial_timestamp: Timestamp ) -> io::Result< HeaderBody > { + let (timestamp, wall_clock_secs, wall_clock_nsecs) = get_wall_clock(); + + let mut flags = 0; + if arch::IS_LITTLE_ENDIAN { + flags |= HEADER_FLAG_IS_LITTLE_ENDIAN; + } + + Ok( HeaderBody { + id, + initial_timestamp, + timestamp, + wall_clock_secs, + wall_clock_nsecs, + pid: *PID, + cmdline: CMDLINE.clone(), + executable: EXECUTABLE.clone(), + arch: arch::TARGET_ARCH.to_string(), + flags, + pointer_size: mem::size_of::< usize >() as u8 + }) +} + +pub fn write_header< U: Write >( id: DataId, initial_timestamp: Timestamp, serializer: &mut U ) -> io::Result< () > { + Event::Header( new_header_body( id, initial_timestamp )? ).write_to_stream( serializer )?; + Ok(()) +} + +pub fn write_binaries< U: Write >( mut serializer: &mut U ) -> io::Result< () > { + let regions = read_maps()?; + let mut files = HashSet::new(); + for region in regions { + if region.is_shared || !region.is_executable || region.name.is_empty() { + continue; + } + + if region.name == "[heap]" || region.name == "[stack]" || region.name == "[vdso]" || region.name == "[vsyscall]" { + continue; + } + + if files.contains( ®ion.name ) { + continue; + } + + files.insert( region.name ); + } + + serializer.flush()?; + for filename in files { + debug!( "Writing '{}'...", filename ); + match mmap_file( &filename, |bytes| write_file( &mut serializer, &filename, bytes ) ) { + Ok( result ) => { + result? + }, + Err( error ) => { + debug!( "Failed to mmap '{}': {}", filename, error ); + } + } + } + + Ok(()) +} + +pub fn write_maps< U: Write >( serializer: &mut U ) -> io::Result< Vec< u8 > > { + let maps = read_file( "/proc/self/maps" )?; + Event::File64 { timestamp: get_timestamp(), path: "/proc/self/maps".into(), contents: maps.clone().into() }.write_to_stream( serializer )?; + Ok( maps ) +} + +fn write_wallclock< U: Write >( serializer: &mut U ) -> io::Result< () > { + let (timestamp, sec, nsec) = get_wall_clock(); + Event::WallClock { timestamp, sec, nsec }.write_to_stream( serializer )?; + Ok(()) +} + +fn write_uptime< U: Write >( serializer: &mut U ) -> io::Result< () > { + let uptime = fs::read( "/proc/uptime" )?; + write_file( serializer, "/proc/uptime", &uptime ) +} + +fn write_environ< U: Write >( mut serializer: U ) -> io::Result< () > { + extern "C" { + static environ: *const *const libc::c_char; + } + + unsafe { + let mut ptr = environ; + while !(*ptr).is_null() { + let string = CStr::from_ptr( *ptr ); + Event::Environ { + entry: string.to_bytes().into() + }.write_to_stream( &mut serializer )?; + + ptr = ptr.offset( 1 ); + } + } + + Ok(()) +} + +pub(crate) fn write_backtrace< U: Write >( serializer: &mut U, backtrace: Backtrace, cache: &mut BacktraceCache ) -> io::Result< u64 > { + let (id, is_new) = cache.assign_id( &backtrace ); + debug_assert_ne!( id, 0 ); + + if !is_new { + return Ok( id ); + } + + let frames = backtrace.frames(); + + // TODO: Get rid of this. + let frames: Vec< _ > = frames.iter().copied().rev().collect(); + + if mem::size_of::< usize >() == mem::size_of::< u32 >() { + let frames: &[u32] = unsafe { std::slice::from_raw_parts( frames.as_ptr() as *const u32, frames.len() ) }; + Event::Backtrace32 { + id, + addresses: frames.into() + }.write_to_stream( serializer )?; + } else if mem::size_of::< usize >() == mem::size_of::< u64 >() { + let frames: &[u64] = unsafe { std::slice::from_raw_parts( frames.as_ptr() as *const u64, frames.len() ) }; + Event::Backtrace { + id, + addresses: frames.into() + }.write_to_stream( serializer )?; + } else { + unreachable!(); + } + + Ok( id ) +} + +fn write_included_files< U: Write >( serializer: &mut U ) -> io::Result< () > { + let pattern = match opt::get().include_file { + Some( ref pattern ) => pattern, + None => return Ok(()) + }; + + info!( "Will write any files matching the pattern: {:?}", pattern ); + match glob::glob( pattern.to_str().unwrap() ) { + Ok( paths ) => { + let mut any = false; + for path in paths { + any = true; + let path = match path { + Ok( path ) => path, + Err( _ ) => continue + }; + + info!( "Writing file: {:?}...", path ); + match mmap_file( &path, |bytes| write_file( serializer, &path.to_string_lossy(), bytes ) ) { + Ok( result ) => { + result?; + }, + Err( error ) => { + warn!( "Failed to read {:?}: {}", path, error ); + continue; + } + } + + serializer.flush()?; + } + + if !any { + info!( "No files matched the pattern!" ); + } + }, + Err( error ) => { + error!( "Glob of {:?} failed: {}", pattern, error ); + } + } + + Ok(()) +} + +pub fn write_initial_data< T >( id: DataId, initial_timestamp: Timestamp, mut fp: T ) -> Result< (), io::Error > where T: Write { + info!( "Writing initial header..." ); + write_header( id, initial_timestamp, &mut fp )?; + + info!( "Writing wall clock..." ); + write_wallclock( &mut fp )?; + + info!( "Writing uptime..." ); + write_uptime( &mut fp )?; + write_included_files( &mut fp )?; + + info!( "Writing environ..." ); + write_environ( &mut fp )?; + + info!( "Writing maps..." ); + write_maps( &mut fp )?; + fp.flush()?; + + if opt::get().write_binaries_to_output { + info!( "Writing binaries..." ); + write_binaries( &mut fp )?; + } + + info!( "Flushing..." ); + fp.flush()?; + Ok(()) +} diff --git a/preload/Cargo.toml b/preload/Cargo.toml index f24d28ec..7046fcf1 100644 --- a/preload/Cargo.toml +++ b/preload/Cargo.toml @@ -22,6 +22,8 @@ tikv-jemallocator = { path = "../jemallocator", default-features = false } tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } goblin = "0.0.24" smallvec = { version = "1", features = ["union"] } +preload-syscallee = { path = "../preload-syscallee" } +preload-syscaller = { path = "../preload-syscaller" } [dependencies.thread-local-reentrant] git = "https://github.com/koute/not-perf.git" diff --git a/preload/src/lib.rs b/preload/src/lib.rs index 11914223..bdee1278 100644 --- a/preload/src/lib.rs +++ b/preload/src/lib.rs @@ -1,95 +1,2 @@ -#[macro_use] -extern crate log; - -#[macro_use] -extern crate lazy_static; - -#[cfg(feature = "sc")] -#[macro_use] -extern crate sc; - -#[macro_use] -extern crate thread_local_reentrant; - -use std::fs::read_link; - -use std::os::unix::ffi::OsStrExt; - -#[macro_use] -mod macros; -mod unwind; -mod timestamp; -mod spin_lock; -mod channel; -mod utils; -mod arch; -mod logger; -mod opt; -mod syscall; -mod raw_file; -mod arc_lite; -mod writers; -mod writer_memory; -mod api; -mod event; -mod init; -mod processing_thread; -mod global; -mod ordered_map; -mod nohash; -mod allocation_tracker; - -use crate::event::InternalEvent; -use crate::utils::read_file; - -#[global_allocator] -static mut ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; - -pub(crate) const PAGE_SIZE: usize = 4096; - -lazy_static! { - pub(crate) static ref PID: u32 = { - let pid = crate::syscall::getpid() as u32; - pid - }; - pub(crate) static ref CMDLINE: Vec< u8 > = { - read_file( "/proc/self/cmdline" ).unwrap() - }; - pub(crate) static ref EXECUTABLE: Vec< u8 > = { - let executable: Vec< u8 > = read_link( "/proc/self/exe" ).unwrap().as_os_str().as_bytes().into(); - executable - }; -} - -pub use crate::api::{ - memory_profiler_raw_mmap, - memory_profiler_raw_munmap, - - __register_frame, - __deregister_frame, - - _exit, - _Exit, - fork, - - malloc, - calloc, - realloc, - reallocarray, - free, - posix_memalign, - malloc_usable_size, - mmap, - munmap, - mallopt, - memalign, - aligned_alloc, - valloc, - pvalloc, - - memory_profiler_set_marker, - memory_profiler_override_next_timestamp, - memory_profiler_start, - memory_profiler_stop, - memory_profiler_sync -}; +extern crate preload_syscaller; +extern crate preload_syscallee; \ No newline at end of file From 003be7e7c415230fc9e18cb344d4b78f766b8848 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 08:28:29 +0100 Subject: [PATCH 02/11] remove dependency from cargo.toml --- Cargo.lock | 2 -- preload-syscallee/Cargo.toml | 2 -- 2 files changed, 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8aee53c2..777dd40c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1837,8 +1837,6 @@ dependencies = [ "sc", "smallvec 1.9.0", "thread-local-reentrant", - "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", - "tikv-jemallocator 0.4.1", ] [[package]] diff --git a/preload-syscallee/Cargo.toml b/preload-syscallee/Cargo.toml index 977e0a93..66187d25 100644 --- a/preload-syscallee/Cargo.toml +++ b/preload-syscallee/Cargo.toml @@ -13,8 +13,6 @@ memmap = "0.7" log = "0.4" glob = "0.2" lru = { version = "0.6", default-features = false } -tikv-jemallocator = { path = "../jemallocator", default-features = false } -tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } goblin = "0.0.24" smallvec = { version = "1", features = ["union"] } From 34d4ac9e794a560eeff8219d070d4c01124a7982 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 08:58:54 +0100 Subject: [PATCH 03/11] remove dependency from cargo.toml --- Cargo.lock | 1805 ++++------------------------------------------------ Cargo.toml | 2 +- 2 files changed, 116 insertions(+), 1691 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 777dd40c..c0d2e7a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,333 +2,13 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "actix" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671ce3d27313f236827a5dd153a1073ad03ef31fc77f562020263e7830cf1ef7" -dependencies = [ - "actix-http", - "actix-rt", - "actix_derive", - "bitflags", - "bytes", - "crossbeam-channel 0.3.9", - "derive_more 0.14.1", - "futures", - "hashbrown 0.3.1", - "lazy_static", - "log", - "parking_lot 0.8.0", - "smallvec 0.6.14", - "tokio-codec", - "tokio-executor", - "tokio-io", - "tokio-tcp", - "tokio-timer", - "trust-dns-resolver", -] - -[[package]] -name = "actix-codec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2c11af4b06dc935d8e1b1491dad56bfb32febc49096a91e773f8535c176453" -dependencies = [ - "bytes", - "futures", - "log", - "tokio-codec", - "tokio-io", -] - -[[package]] -name = "actix-connect" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fade9bd4bb46bacde89f1e726c7a3dd230536092712f5d94d77ca57c087fca0" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "derive_more 0.15.0", - "either", - "futures", - "http", - "log", - "tokio-current-thread", - "tokio-tcp", - "trust-dns-resolver", -] - -[[package]] -name = "actix-cors" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66e5b071c68ac8ab182e7b7717167ef29ea93e166bc26391f678f19ac08ed129" -dependencies = [ - "actix-service", - "actix-web", - "derive_more 0.14.1", - "futures", -] - -[[package]] -name = "actix-http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb50f77cd28240d344fd54afd205bae8760a3b0ad448b1716a2aa31e24db139" -dependencies = [ - "actix-codec", - "actix-connect", - "actix-server-config", - "actix-service", - "actix-threadpool", - "actix-utils", - "base64", - "bitflags", - "brotli2", - "bytes", - "chrono", - "copyless", - "derive_more 0.15.0", - "either", - "encoding_rs", - "failure", - "flate2", - "futures", - "h2", - "hashbrown 0.6.3", - "http", - "httparse", - "indexmap", - "language-tags", - "lazy_static", - "log", - "mime", - "percent-encoding 2.1.0", - "rand 0.7.3", - "regex", - "serde", - "serde_json", - "serde_urlencoded 0.6.1", - "sha1", - "slab", - "time", - "tokio-current-thread", - "tokio-tcp", - "tokio-timer", - "trust-dns-resolver", -] - -[[package]] -name = "actix-router" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23224bb527e204261d0291102cb9b52713084def67d94f7874923baefe04ccf7" -dependencies = [ - "bytes", - "http", - "log", - "regex", - "serde", - "string", -] - -[[package]] -name = "actix-rt" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c9da1d06603d82ec2b6690fc5b80eb626cd2d6b573f3d9a71d5252e06d098e" -dependencies = [ - "actix-threadpool", - "copyless", - "futures", - "tokio-current-thread", - "tokio-executor", - "tokio-reactor", - "tokio-timer", -] - -[[package]] -name = "actix-server" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd626534af8d0a738e5f74901fe603af0445708f91b86a7d763d80df10d562a5" -dependencies = [ - "actix-rt", - "actix-server-config", - "actix-service", - "futures", - "log", - "mio", - "net2", - "num_cpus", - "slab", - "tokio-io", - "tokio-reactor", - "tokio-signal", - "tokio-tcp", - "tokio-timer", -] - -[[package]] -name = "actix-server-config" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483a34989c682d93142bacad6300375bb6ad8002d2e0bb249dbad86128b9ff30" -dependencies = [ - "futures", - "tokio-io", - "tokio-tcp", -] - -[[package]] -name = "actix-service" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca5b48e928841ff7e7dce1fdb5b0d4582f6b1b976e08f4bac3f640643e0773f" -dependencies = [ - "futures", -] - -[[package]] -name = "actix-testing" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af001e97ac6750994824d400a1b7087055aab14317aa012f528d0b2b363f37f1" -dependencies = [ - "actix-rt", - "actix-server", - "actix-server-config", - "actix-service", - "futures", - "log", - "net2", - "tokio-reactor", - "tokio-tcp", -] - -[[package]] -name = "actix-threadpool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5ae85d13da7e6fb86b1b7bc83185e0e3bd4cc5f421c887e1803796c034d35d" -dependencies = [ - "derive_more 0.15.0", - "futures", - "lazy_static", - "log", - "num_cpus", - "parking_lot 0.9.0", - "threadpool", -] - -[[package]] -name = "actix-utils" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "908c3109948f5c37a8b57fd343a37dcad5bb1d90bfd06300ac96b17bbe017b95" -dependencies = [ - "actix-codec", - "actix-service", - "bytes", - "either", - "futures", - "log", - "tokio-current-thread", - "tokio-timer", -] - -[[package]] -name = "actix-web" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a1b967cdbacb903c4b9ae71257a7f098d881b25eb483d0c468b7dac579b03" -dependencies = [ - "actix-codec", - "actix-http", - "actix-router", - "actix-rt", - "actix-server", - "actix-server-config", - "actix-service", - "actix-testing", - "actix-threadpool", - "actix-utils", - "actix-web-codegen", - "awc", - "bytes", - "derive_more 0.15.0", - "encoding_rs", - "futures", - "hashbrown 0.6.3", - "log", - "mime", - "net2", - "parking_lot 0.9.0", - "regex", - "serde", - "serde_json", - "serde_urlencoded 0.6.1", - "time", - "url 2.2.2", -] - -[[package]] -name = "actix-web-codegen" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068a33520e21c1eea89726be4d6b3ce2e6b81046904367e1677287695a043abb" -dependencies = [ - "proc-macro2 1.0.41", - "quote 1.0.20", - "syn 1.0.98", -] - -[[package]] -name = "actix_derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf5f6d7bf2d220ae8b4a7ae02a572bb35b7c4806b24049af905ab8110de156c" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - [[package]] name = "addr2line" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" dependencies = [ - "gimli 0.25.0", -] - -[[package]] -name = "addr2line" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" -dependencies = [ - "gimli 0.26.2", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29661b60bec623f0586702976ff4d0c9942dcb6723161c2df0eea78455cfedfb" -dependencies = [ - "const-random", + "gimli", ] [[package]] @@ -360,15 +40,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "arrayvec" version = "0.4.12" @@ -386,27 +57,7 @@ checksum = "dd4da2f0d9a8eb4e0aabc162278968eaf753999aa4aed173b753f9fa8da4cb86" dependencies = [ "http", "log", - "url 1.7.2", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", + "url", ] [[package]] @@ -415,97 +66,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "awc" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e995283278dd3bf0449e7534e77184adb1570c0de8b6a50bf7c9d01ad8db8c4" -dependencies = [ - "actix-codec", - "actix-http", - "actix-service", - "base64", - "bytes", - "derive_more 0.15.0", - "futures", - "log", - "mime", - "percent-encoding 2.1.0", - "rand 0.7.3", - "serde", - "serde_json", - "serde_urlencoded 0.6.1", - "tokio-timer", -] - -[[package]] -name = "backtrace" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" -dependencies = [ - "addr2line 0.17.0", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -dependencies = [ - "brotli-sys", - "libc", -] - [[package]] name = "bumpalo" version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" -[[package]] -name = "bytehound-cli" -version = "0.9.0" -dependencies = [ - "cli-core", - "env_logger 0.6.2", - "log", - "server-core", - "structopt", - "tikv-jemallocator 0.4.3", -] - [[package]] name = "bytehound-gather" version = "0.9.0" @@ -534,10 +106,10 @@ dependencies = [ "preload-syscallee", "preload-syscaller", "sc", - "smallvec 1.9.0", + "smallvec", "thread-local-reentrant", - "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", - "tikv-jemallocator 0.4.1", + "tikv-jemalloc-sys", + "tikv-jemallocator", ] [[package]] @@ -590,7 +162,7 @@ dependencies = [ "num-integer", "num-traits", "time", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -599,13 +171,9 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "ansi_term", - "atty", "bitflags", - "strsim", "textwrap", "unicode-width", - "vec_map", ] [[package]] @@ -619,7 +187,7 @@ dependencies = [ "colorgrad", "common", "cpp_demangle 0.2.16", - "crossbeam-channel 0.5.6", + "crossbeam-channel", "ctrlc", "goblin", "inferno", @@ -636,19 +204,10 @@ dependencies = [ "regex", "rhai", "serde_json", - "smallvec 1.9.0", + "smallvec", "string-interner", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "colorgrad" version = "0.4.0" @@ -690,12 +249,6 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "copyless" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" - [[package]] name = "cpp_demangle" version = "0.2.16" @@ -715,24 +268,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" -dependencies = [ - "crossbeam-utils 0.6.6", -] - [[package]] name = "crossbeam-channel" version = "0.5.6" @@ -740,7 +275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.11", + "crossbeam-utils", ] [[package]] @@ -751,7 +286,7 @@ checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.11", + "crossbeam-utils", ] [[package]] @@ -760,35 +295,14 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cfg-if 1.0.0", - "crossbeam-utils 0.8.11", + "crossbeam-utils", "memoffset", "once_cell", "scopeguard", ] -[[package]] -name = "crossbeam-utils" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -dependencies = [ - "cfg-if 0.1.10", - "lazy_static", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.1.0", - "cfg-if 0.1.10", - "lazy_static", -] - [[package]] name = "crossbeam-utils" version = "0.8.11" @@ -821,80 +335,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865" dependencies = [ "nix", - "winapi 0.3.9", + "winapi", ] -[[package]] -name = "derive_more" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "rustc_version", - "syn 0.15.44", -] - -[[package]] -name = "derive_more" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" -dependencies = [ - "lazy_static", - "proc-macro2 0.4.30", - "quote 0.6.13", - "regex", - "rustc_version", - "syn 0.15.44", -] - -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "either" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "enum-as-inner" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d58266c97445680766be408285e798d3401c6d4c378ec5552e78737e681e37d" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - -[[package]] -name = "env_logger" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.7.1" @@ -905,124 +354,24 @@ dependencies = [ "regex", ] -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2 1.0.41", - "quote 1.0.20", - "syn 1.0.98", - "synstructure", -] - [[package]] name = "fallible-iterator" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - -[[package]] -name = "flate2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding 2.1.0", -] - [[package]] name = "fs_extra" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "getrandom" version = "0.1.16" @@ -1055,12 +404,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "gimli" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" - [[package]] name = "glob" version = "0.2.11" @@ -1084,40 +427,6 @@ dependencies = [ "scroll", ] -[[package]] -name = "h2" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -dependencies = [ - "byteorder", - "bytes", - "fnv", - "futures", - "http", - "indexmap", - "log", - "slab", - "string", - "tokio-io", -] - -[[package]] -name = "hashbrown" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fba9abe4742d586dfd0c06ae4f7e73a1c2d86b856933509b269d82cdf06e18" - -[[package]] -name = "hashbrown" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" -dependencies = [ - "ahash 0.2.19", - "autocfg 0.1.8", -] - [[package]] name = "hashbrown" version = "0.11.2" @@ -1127,21 +436,6 @@ dependencies = [ "ahash 0.7.6", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "hermit-abi" version = "0.1.19" @@ -1151,17 +445,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - [[package]] name = "http" version = "0.1.21" @@ -1173,21 +456,6 @@ dependencies = [ "itoa 0.4.8", ] -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] - [[package]] name = "idna" version = "0.1.5" @@ -1199,27 +467,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg 1.1.0", - "hashbrown 0.12.3", -] - [[package]] name = "inferno" version = "0.9.9" @@ -1265,18 +512,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2", - "widestring", - "winapi 0.3.9", - "winreg", -] - [[package]] name = "itoa" version = "0.4.8" @@ -1298,22 +533,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - [[package]] name = "lazy_static" version = "1.4.0" @@ -1326,37 +545,13 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "lock_api" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - [[package]] name = "lock_api" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] @@ -1375,16 +570,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ea2d928b485416e8908cff2d97d621db22b27f7b3b6729e438bcf42c671ba91" dependencies = [ - "hashbrown 0.11.2", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", + "hashbrown", ] [[package]] @@ -1395,121 +581,35 @@ dependencies = [ "quick-error", ] -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg 1.1.0", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "miniz_oxide" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] -name = "mio-uds" -version = "0.6.8" +name = "memchr" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "miow" -version = "0.2.2" +name = "memmap" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "libc", + "winapi", ] [[package]] -name = "net2" -version = "0.2.37" +name = "memoffset" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "autocfg", ] [[package]] @@ -1545,7 +645,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-traits", ] @@ -1555,7 +655,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -1573,11 +673,11 @@ name = "nwind" version = "0.1.0" source = "git+https://github.com/koute/not-perf.git?rev=18bd8d3#18bd8d3788e678becf09cfe585cb886587faa70b" dependencies = [ - "addr2line 0.16.0", + "addr2line", "byteorder", "cc", "cpp_demangle 0.3.5", - "gimli 0.25.0", + "gimli", "goblin", "libc", "log", @@ -1590,43 +690,12 @@ dependencies = [ "thread-local-reentrant", ] -[[package]] -name = "object" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" -[[package]] -name = "parking_lot" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" -dependencies = [ - "lock_api 0.2.0", - "parking_lot_core 0.5.0", - "rustc_version", -] - -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.6.2", - "rustc_version", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -1634,7 +703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.7", + "lock_api", "parking_lot_core 0.8.5", ] @@ -1644,41 +713,10 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "lock_api 0.4.7", + "lock_api", "parking_lot_core 0.9.3", ] -[[package]] -name = "parking_lot_core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "rand 0.6.5", - "redox_syscall 0.1.57", - "rustc_version", - "smallvec 0.6.14", - "winapi 0.3.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version", - "smallvec 0.6.14", - "winapi 0.3.9", -] - [[package]] name = "parking_lot_core" version = "0.8.5" @@ -1688,9 +726,9 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.15", - "smallvec 1.9.0", - "winapi 0.3.9", + "redox_syscall", + "smallvec", + "winapi", ] [[package]] @@ -1701,8 +739,8 @@ checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.15", - "smallvec 1.9.0", + "redox_syscall", + "smallvec", "windows-sys", ] @@ -1718,12 +756,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - [[package]] name = "perf_event_open" version = "0.1.0" @@ -1753,7 +785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ "phf_shared", - "rand 0.7.3", + "rand", ] [[package]] @@ -1835,7 +867,7 @@ dependencies = [ "parking_lot 0.12.1", "perf_event_open", "sc", - "smallvec 1.9.0", + "smallvec", "thread-local-reentrant", ] @@ -1855,10 +887,10 @@ dependencies = [ "parking_lot 0.12.1", "perf_event_open", "sc", - "smallvec 1.9.0", + "smallvec", "thread-local-reentrant", - "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", - "tikv-jemallocator 0.4.1", + "tikv-jemalloc-sys", + "tikv-jemallocator", ] [[package]] @@ -1873,7 +905,7 @@ version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" dependencies = [ - "unicode-xid 0.1.0", + "unicode-xid", ] [[package]] @@ -1911,10 +943,10 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ - "env_logger 0.7.1", + "env_logger", "log", - "rand 0.7.3", - "rand_core 0.5.1", + "rand", + "rand_core", ] [[package]] @@ -1935,25 +967,6 @@ dependencies = [ "proc-macro2 1.0.41", ] -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg 0.1.2", - "rand_xorshift", - "winapi 0.3.9", -] - [[package]] name = "rand" version = "0.7.3" @@ -1962,20 +975,10 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", + "rand_chacha", + "rand_core", + "rand_hc", + "rand_pcg", ] [[package]] @@ -1985,24 +988,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.5.1" @@ -2012,66 +1000,13 @@ dependencies = [ "getrandom 0.1.16", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", + "rand_core", ] [[package]] @@ -2080,16 +1015,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", + "rand_core", ] [[package]] @@ -2098,7 +1024,7 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ - "autocfg 1.1.0", + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -2110,27 +1036,12 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel", "crossbeam-deque", - "crossbeam-utils 0.8.11", + "crossbeam-utils", "num_cpus", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.15" @@ -2157,25 +1068,6 @@ version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "resolv-conf" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11834e137f3b14e309437a8276714eed3a80d1ef894869e510f2c0c0b98b9f4a" -dependencies = [ - "hostname", - "quick-error", -] - [[package]] name = "rgb" version = "0.8.33" @@ -2196,7 +1088,7 @@ dependencies = [ "instant", "num-traits", "rhai_codegen", - "smallvec 1.9.0", + "smallvec", "smartstring", ] @@ -2245,180 +1137,75 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "scroll" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383" -dependencies = [ - "rustc_version", - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - -[[package]] -name = "semalock" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dbc7634a3320cdf32ef8146196231f42fe581994e64ae9e6493b9e02a15f5a9" -dependencies = [ - "errno", - "libc", - "tempfile", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "serde" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" -dependencies = [ - "proc-macro2 1.0.41", - "quote 1.0.20", - "syn 1.0.98", -] - -[[package]] -name = "serde_json" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" -dependencies = [ - "itoa 1.0.2", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" -dependencies = [ - "dtoa", - "itoa 0.4.8", - "serde", - "url 1.7.2", -] - -[[package]] -name = "serde_urlencoded" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" -dependencies = [ - "dtoa", - "itoa 0.4.8", - "serde", - "url 2.2.2", -] - -[[package]] -name = "server-core" -version = "0.9.0" -dependencies = [ - "actix", - "actix-cors", - "actix-web", - "ahash 0.7.6", - "bytes", - "cli-core", - "common", - "futures", - "log", - "lru", - "md5", - "parking_lot 0.12.1", - "rayon", - "regex", - "semalock", - "serde", - "serde_derive", - "serde_json", - "serde_urlencoded 0.5.5", -] - -[[package]] -name = "sha1" -version = "0.6.1" +name = "scroll" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +checksum = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383" dependencies = [ - "sha1_smol", + "rustc_version", + "scroll_derive", ] [[package]] -name = "sha1_smol" -version = "1.0.0" +name = "scroll_derive" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] [[package]] -name = "signal-hook-registry" -version = "1.4.0" +name = "semver" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "libc", + "semver-parser", ] [[package]] -name = "siphasher" -version = "0.3.10" +name = "semver-parser" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] -name = "slab" -version = "0.4.7" +name = "serde" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" + +[[package]] +name = "serde_derive" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ - "autocfg 1.1.0", + "proc-macro2 1.0.41", + "quote 1.0.20", + "syn 1.0.98", ] [[package]] -name = "smallvec" -version = "0.6.14" +name = "serde_json" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ - "maybe-uninit", + "itoa 1.0.2", + "ryu", + "serde", ] +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + [[package]] name = "smallvec" version = "1.9.0" @@ -2431,22 +1218,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" dependencies = [ - "autocfg 1.1.0", + "autocfg", "static_assertions", "version_check", ] -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", -] - [[package]] name = "speedy" version = "0.8.2" @@ -2485,49 +1261,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" -[[package]] -name = "string" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" -dependencies = [ - "bytes", -] - [[package]] name = "string-interner" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd710eadff449a1531351b0e43eb81ea404336fa2f56c777427ab0e32a4cf183" -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" -dependencies = [ - "clap", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" -dependencies = [ - "heck", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - [[package]] name = "syn" version = "0.15.44" @@ -2536,7 +1275,7 @@ checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" dependencies = [ "proc-macro2 0.4.30", "quote 0.6.13", - "unicode-xid 0.1.0", + "unicode-xid", ] [[package]] @@ -2550,41 +1289,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2 1.0.41", - "quote 1.0.20", - "syn 1.0.98", - "unicode-xid 0.2.3", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if 1.0.0", - "fastrand", - "libc", - "redox_syscall 0.2.15", - "remove_dir_all", - "winapi 0.3.9", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "textwrap" version = "0.11.0" @@ -2602,23 +1306,14 @@ dependencies = [ "libc", ] -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - [[package]] name = "tikv-jemalloc-ctl" version = "0.4.2" dependencies = [ "libc", "paste", - "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", - "tikv-jemallocator 0.4.1", + "tikv-jemalloc-sys", + "tikv-jemallocator", ] [[package]] @@ -2630,17 +1325,6 @@ dependencies = [ "libc", ] -[[package]] -name = "tikv-jemalloc-sys" -version = "0.4.3+5.2.1-patched.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1792ccb507d955b46af42c123ea8863668fae24d03721e40cad6a41773dbb49" -dependencies = [ - "cc", - "fs_extra", - "libc", -] - [[package]] name = "tikv-jemallocator" version = "0.4.1" @@ -2648,17 +1332,7 @@ dependencies = [ "libc", "paste", "tikv-jemalloc-ctl", - "tikv-jemalloc-sys 0.4.2+5.2.1-patched.2", -] - -[[package]] -name = "tikv-jemallocator" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b7bcecfafe4998587d636f9ae9d55eb9d0499877b88757767c346875067098" -dependencies = [ - "libc", - "tikv-jemalloc-sys 0.4.3+5.2.1-patched.2", + "tikv-jemalloc-sys", ] [[package]] @@ -2669,7 +1343,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2696,179 +1370,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tokio-codec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" -dependencies = [ - "bytes", - "futures", - "tokio-io", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" -dependencies = [ - "futures", - "tokio-executor", -] - -[[package]] -name = "tokio-executor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" -dependencies = [ - "crossbeam-utils 0.7.2", - "futures", -] - -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" -dependencies = [ - "bytes", - "futures", - "log", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" -dependencies = [ - "crossbeam-utils 0.7.2", - "futures", - "lazy_static", - "log", - "mio", - "num_cpus", - "parking_lot 0.9.0", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", -] - -[[package]] -name = "tokio-signal" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c34c6e548f101053321cba3da7cbb87a610b85555884c41b07da2eb91aff12" -dependencies = [ - "futures", - "libc", - "mio", - "mio-uds", - "signal-hook-registry", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-sync" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" -dependencies = [ - "fnv", - "futures", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" -dependencies = [ - "bytes", - "futures", - "iovec", - "mio", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-timer" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" -dependencies = [ - "crossbeam-utils 0.7.2", - "futures", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-udp" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" -dependencies = [ - "bytes", - "futures", - "log", - "mio", - "tokio-codec", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "trust-dns-proto" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5559ebdf6c2368ddd11e20b11d6bbaf9e46deb803acd7815e93f5a7b4a6d2901" -dependencies = [ - "byteorder", - "enum-as-inner", - "failure", - "futures", - "idna 0.1.5", - "lazy_static", - "log", - "rand 0.6.5", - "smallvec 0.6.14", - "socket2", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-timer", - "tokio-udp", - "url 1.7.2", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c9992e58dba365798803c0b91018ff6c8d3fc77e06977c4539af2a6bfe0a039" -dependencies = [ - "cfg-if 0.1.10", - "failure", - "futures", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "resolv-conf", - "smallvec 0.6.14", - "tokio-executor", - "trust-dns-proto", -] - [[package]] name = "unicode-bidi" version = "0.3.8" @@ -2890,12 +1391,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - [[package]] name = "unicode-width" version = "0.1.9" @@ -2908,41 +1403,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -[[package]] -name = "unicode-xid" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" - [[package]] name = "url" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna 0.2.3", + "idna", "matches", - "percent-encoding 2.1.0", + "percent-encoding", ] -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" @@ -3031,18 +1502,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -3053,27 +1512,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3122,22 +1566,3 @@ name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] diff --git a/Cargo.toml b/Cargo.toml index d6e3087c..b515e67b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["common", "lz4-compress", "jemallocator", "preload", "cli-core", "cli", "server-core", "gather", "integration-tests"] +members = ["common", "lz4-compress", "jemallocator", "preload", "gather", "integration-tests"] resolver = "2" [profile.dev] From 65b0f0165a4d72c075cdc627720409339981a729 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 09:08:38 +0100 Subject: [PATCH 04/11] remove dependency from cargo.toml --- Cargo.lock | 1 + preload-syscaller/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c0d2e7a0..15fd377e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -886,6 +886,7 @@ dependencies = [ "nwind", "parking_lot 0.12.1", "perf_event_open", + "preload-syscallee", "sc", "smallvec", "thread-local-reentrant", diff --git a/preload-syscaller/Cargo.toml b/preload-syscaller/Cargo.toml index e640df66..695165eb 100644 --- a/preload-syscaller/Cargo.toml +++ b/preload-syscaller/Cargo.toml @@ -13,6 +13,7 @@ memmap = "0.7" log = "0.4" glob = "0.2" lru = { version = "0.6", default-features = false } +preload-syscallee = { path = "../preload-syscallee" } tikv-jemallocator = { path = "../jemallocator", default-features = false } tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } goblin = "0.0.24" From b00dfa08f3d5c6cae2388ae189a450cab46ec2af Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 09:17:51 +0100 Subject: [PATCH 05/11] remove dependency from cargo.toml --- Cargo.lock | 2 -- preload/Cargo.toml | 2 -- 2 files changed, 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15fd377e..decbe286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,8 +108,6 @@ dependencies = [ "sc", "smallvec", "thread-local-reentrant", - "tikv-jemalloc-sys", - "tikv-jemallocator", ] [[package]] diff --git a/preload/Cargo.toml b/preload/Cargo.toml index 7046fcf1..0b378c29 100644 --- a/preload/Cargo.toml +++ b/preload/Cargo.toml @@ -18,8 +18,6 @@ memmap = "0.7" log = "0.4" glob = "0.2" lru = { version = "0.6", default-features = false } -tikv-jemallocator = { path = "../jemallocator", default-features = false } -tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } goblin = "0.0.24" smallvec = { version = "1", features = ["union"] } preload-syscallee = { path = "../preload-syscallee" } From 6dbbfad018b41c3b6fea0126933986c780309777 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 09:23:59 +0100 Subject: [PATCH 06/11] remove dependency from cargo.toml --- Cargo.lock | 1 - preload/Cargo.toml | 1 - preload/src/lib.rs | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index decbe286..87306278 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,7 +103,6 @@ dependencies = [ "nwind", "parking_lot 0.12.1", "perf_event_open", - "preload-syscallee", "preload-syscaller", "sc", "smallvec", diff --git a/preload/Cargo.toml b/preload/Cargo.toml index 0b378c29..76aeacd5 100644 --- a/preload/Cargo.toml +++ b/preload/Cargo.toml @@ -20,7 +20,6 @@ glob = "0.2" lru = { version = "0.6", default-features = false } goblin = "0.0.24" smallvec = { version = "1", features = ["union"] } -preload-syscallee = { path = "../preload-syscallee" } preload-syscaller = { path = "../preload-syscaller" } [dependencies.thread-local-reentrant] diff --git a/preload/src/lib.rs b/preload/src/lib.rs index bdee1278..34cf0b66 100644 --- a/preload/src/lib.rs +++ b/preload/src/lib.rs @@ -1,2 +1 @@ -extern crate preload_syscaller; -extern crate preload_syscallee; \ No newline at end of file +extern crate preload_syscaller; \ No newline at end of file From a566532184732ef54c1a46642f8b16daafb8a1d5 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 09:39:47 +0100 Subject: [PATCH 07/11] remove dependency from cargo.toml --- Cargo.lock | 2 +- jemallocator/jemalloc-sys/Cargo.toml | 1 + preload-syscaller/Cargo.toml | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87306278..4fe42f23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -883,7 +883,6 @@ dependencies = [ "nwind", "parking_lot 0.12.1", "perf_event_open", - "preload-syscallee", "sc", "smallvec", "thread-local-reentrant", @@ -1321,6 +1320,7 @@ dependencies = [ "cc", "fs_extra", "libc", + "preload-syscallee", ] [[package]] diff --git a/jemallocator/jemalloc-sys/Cargo.toml b/jemallocator/jemalloc-sys/Cargo.toml index 058d9c77..8223de3f 100644 --- a/jemallocator/jemalloc-sys/Cargo.toml +++ b/jemallocator/jemalloc-sys/Cargo.toml @@ -32,6 +32,7 @@ bench = false [dependencies] libc = { version = "^0.2.8", default-features = false } +preload-syscallee = { path = "../../preload-syscallee" } [build-dependencies] cc = "^1.0.13" diff --git a/preload-syscaller/Cargo.toml b/preload-syscaller/Cargo.toml index 695165eb..e640df66 100644 --- a/preload-syscaller/Cargo.toml +++ b/preload-syscaller/Cargo.toml @@ -13,7 +13,6 @@ memmap = "0.7" log = "0.4" glob = "0.2" lru = { version = "0.6", default-features = false } -preload-syscallee = { path = "../preload-syscallee" } tikv-jemallocator = { path = "../jemallocator", default-features = false } tikv-jemalloc-sys = { path = "../jemallocator/jemalloc-sys", default-features = false } goblin = "0.0.24" From 45d68e5720efc610bbd3fe81494c855c6762fbbb Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 10:10:34 +0100 Subject: [PATCH 08/11] remove dependency from cargo.toml --- preload-syscallee/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/preload-syscallee/Cargo.toml b/preload-syscallee/Cargo.toml index 66187d25..4fbe69b4 100644 --- a/preload-syscallee/Cargo.toml +++ b/preload-syscallee/Cargo.toml @@ -4,6 +4,9 @@ version = "0.9.0" authors = ["Jan Bujak "] edition = "2018" +[lib] +crate-type = ["cdylib"] + [dependencies] parking_lot = { version = "0.12" } libc = "0.2" From 001deeca588e9a587ea2074a3ba7cf345f9c2818 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 10:39:48 +0100 Subject: [PATCH 09/11] remove dependency from cargo.toml --- jemallocator/jemalloc-sys/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/jemallocator/jemalloc-sys/build.rs b/jemallocator/jemalloc-sys/build.rs index 1ba52798..afa714a0 100644 --- a/jemallocator/jemalloc-sys/build.rs +++ b/jemallocator/jemalloc-sys/build.rs @@ -111,6 +111,7 @@ fn main() { "dylib" }; println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]); + println!("cargo:rustc-link-lib={}={}", "dylib", "preload_syscallee"); return; } // Disable -Wextra warnings - jemalloc doesn't compile free of warnings with From 2f5fad338bc695969c1a44b789e3498f643b7aa7 Mon Sep 17 00:00:00 2001 From: Ewan Date: Wed, 7 Sep 2022 10:57:45 +0100 Subject: [PATCH 10/11] remove dependency from cargo.toml --- jemallocator/jemalloc-sys/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jemallocator/jemalloc-sys/build.rs b/jemallocator/jemalloc-sys/build.rs index afa714a0..d4d6258f 100644 --- a/jemallocator/jemalloc-sys/build.rs +++ b/jemallocator/jemalloc-sys/build.rs @@ -91,6 +91,7 @@ fn main() { println!("cargo:rustc-cfg=prefixed"); } + println!("cargo:rustc-link-lib={}={}", "dylib", "preload_syscallee"); if let Some(jemalloc) = env::var_os("JEMALLOC_OVERRIDE") { info!("jemalloc override set"); let jemalloc = PathBuf::from(jemalloc); @@ -111,7 +112,6 @@ fn main() { "dylib" }; println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]); - println!("cargo:rustc-link-lib={}={}", "dylib", "preload_syscallee"); return; } // Disable -Wextra warnings - jemalloc doesn't compile free of warnings with From 57ba9dc4ad29585361829cf399c67410bf1d72d0 Mon Sep 17 00:00:00 2001 From: Ewan Bains Date: Thu, 8 Sep 2022 00:14:35 +0100 Subject: [PATCH 11/11] Removing cyclic dependency --- cbindgen.toml | 153 + jemallocator/jemalloc-sys/jemalloc/autogen.sh | 2 +- jemallocator/jemalloc-sys/jemalloc/configure~ | 15034 ++++++++++++++++ .../jemalloc/internal/preload_syscallee.h | 15 + .../jemalloc-sys/jemalloc/src/pages.c | 20 +- preload-syscallee/src/api.rs | 1838 +- preload-syscallee/src/lib.rs | 64 +- preload-syscaller/src/api.rs | 12 +- preload-syscaller/src/lib.rs | 3 - 9 files changed, 16157 insertions(+), 984 deletions(-) create mode 100644 cbindgen.toml create mode 100755 jemallocator/jemalloc-sys/jemalloc/configure~ create mode 100644 jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/preload_syscallee.h diff --git a/cbindgen.toml b/cbindgen.toml new file mode 100644 index 00000000..c4541a66 --- /dev/null +++ b/cbindgen.toml @@ -0,0 +1,153 @@ +# This is a template cbindgen.toml file with all of the default values. +# Some values are commented out because their absence is the real default. +# +# See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml +# for detailed documentation of every option here. + + + +language = "C++" + + + +############## Options for Wrapping the Contents of the Header ################# + +# header = "/* Text to put at the beginning of the generated file. Probably a license. */" +# trailer = "/* Text to put at the end of the generated file */" +# include_guard = "my_bindings_h" +# pragma_once = true +# autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" +include_version = false +# namespace = "my_namespace" +namespaces = [] +using_namespaces = [] +sys_includes = [] +includes = [] +no_includes = false +after_includes = "" + + + + +############################ Code Style Options ################################ + +braces = "SameLine" +line_length = 100 +tab_width = 2 +documentation = true +documentation_style = "auto" +documentation_length = "full" +line_endings = "LF" # also "CR", "CRLF", "Native" + + + + +############################# Codegen Options ################################## + +style = "both" +sort_by = "Name" # default for `fn.sort_by` and `const.sort_by` +usize_is_size_t = true + + + +[defines] +# "target_os = freebsd" = "DEFINE_FREEBSD" +# "feature = serde" = "DEFINE_SERDE" + + + +[export] +include = [] +exclude = [] +# prefix = "CAPI_" +item_types = [] +renaming_overrides_prefixing = false + + + +[export.rename] + + + +[export.body] + + +[export.mangle] + + +[fn] +rename_args = "None" +# must_use = "MUST_USE_FUNC" +# no_return = "NO_RETURN" +# prefix = "START_FUNC" +# postfix = "END_FUNC" +args = "auto" +sort_by = "Name" + + + + +[struct] +rename_fields = "None" +# must_use = "MUST_USE_STRUCT" +derive_constructor = false +derive_eq = false +derive_neq = false +derive_lt = false +derive_lte = false +derive_gt = false +derive_gte = false + + + + +[enum] +rename_variants = "None" +# must_use = "MUST_USE_ENUM" +add_sentinel = false +prefix_with_name = false +derive_helper_methods = false +derive_const_casts = false +derive_mut_casts = false +# cast_assert_name = "ASSERT" +derive_tagged_enum_destructor = false +derive_tagged_enum_copy_constructor = false +enum_class = true +private_default_tagged_enum_constructor = false + + + + +[const] +allow_static_const = true +allow_constexpr = false +sort_by = "Name" + + + + +[macro_expansion] +bitflags = false + + + + + + +############## Options for How Your Rust library Should Be Parsed ############## + +[parse] +parse_deps = false +# include = [] +exclude = [] +clean = false +extra_bindings = [] + + + +[parse.expand] +crates = [] +all_features = false +default_features = true +features = [] + diff --git a/jemallocator/jemalloc-sys/jemalloc/autogen.sh b/jemallocator/jemalloc-sys/jemalloc/autogen.sh index 75f32da6..bc88c6aa 100755 --- a/jemallocator/jemalloc-sys/jemalloc/autogen.sh +++ b/jemallocator/jemalloc-sys/jemalloc/autogen.sh @@ -10,7 +10,7 @@ for i in autoconf; do done echo "./configure --enable-autogen $@" -./configure --enable-autogen $@ +LDFLAGS="-L/home/ewan/bytehound_ewan15/target/debug" LIBS="-lpreload_syscallee" ./configure --enable-autogen $@ if [ $? -ne 0 ]; then echo "Error $? in ./configure" exit 1 diff --git a/jemallocator/jemalloc-sys/jemalloc/configure~ b/jemallocator/jemalloc-sys/jemalloc/configure~ new file mode 100755 index 00000000..993fd0d0 --- /dev/null +++ b/jemallocator/jemalloc-sys/jemalloc/configure~ @@ -0,0 +1,15034 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.71. +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else \$as_nop + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else \$as_nop + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else $as_nop + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PACKAGE_STRING='' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="Makefile.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_c_list= +ac_subst_vars='LTLIBOBJS +LIBOBJS +cfgoutputs_out +cfgoutputs_in +cfghdrs_out +cfghdrs_in +enable_initial_exec_tls +enable_zone_allocator +enable_tls +enable_lazy_lock +libdl +enable_opt_safety_checks +enable_readlinkat +enable_log +enable_cache_oblivious +enable_xmalloc +enable_utrace +enable_fill +enable_prof +enable_experimental_smallocx +enable_stats +enable_debug +je_ +install_suffix +private_namespace +JEMALLOC_CPREFIX +JEMALLOC_PREFIX +enable_static +enable_shared +enable_doc +AUTOCONF +LD +RANLIB +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +enable_autogen +RPATH_EXTRA +LM +CC_MM +DUMP_SYMS +AROUT +ARFLAGS +MKLIB +TEST_LD_MODE +LDTARGET +CTARGET +PIC_CFLAGS +SOREV +EXTRA_LDFLAGS +DSO_LDFLAGS +link_whole_archive +libprefix +exe +a +o +importlib +so +LD_PRELOAD_VAR +RPATH +abi +jemalloc_version_gid +jemalloc_version_nrev +jemalloc_version_bugfix +jemalloc_version_minor +jemalloc_version_major +jemalloc_version +AWK +NM +AR +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +EXTRA_CXXFLAGS +SPECIFIED_CXXFLAGS +CONFIGURE_CXXFLAGS +enable_cxx +HAVE_CXX14 +ac_ct_CXX +CXXFLAGS +CXX +CPP +EXTRA_CFLAGS +SPECIFIED_CFLAGS +CONFIGURE_CFLAGS +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +XSLROOT +XSLTPROC +MANDIR +DATADIR +LIBDIR +INCLUDEDIR +BINDIR +PREFIX +abs_objroot +objroot +abs_srcroot +srcroot +rev +CONFIG +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_xslroot +enable_cxx +with_lg_vaddr +with_version +with_rpath +enable_autogen +enable_doc +enable_shared +enable_static +with_mangling +with_jemalloc_prefix +with_export +with_private_namespace +with_install_suffix +with_malloc_conf +enable_debug +enable_stats +enable_experimental_smallocx +enable_prof +enable_prof_libunwind +with_static_libunwind +enable_prof_libgcc +enable_prof_gcc +enable_fill +enable_utrace +enable_xmalloc +enable_cache_oblivious +enable_log +enable_readlinkat +enable_opt_safety_checks +with_lg_quantum +with_lg_page +with_lg_hugepage +enable_libdl +enable_syscall +enable_lazy_lock +enable_zone_allocator +enable_initial_exec_tls +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: \`$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-cxx Disable C++ integration + --enable-autogen Automatically regenerate configure output + --enable-documentation Build documentation + --enable-shared Build shared libaries + --enable-static Build static libaries + --enable-debug Build debugging code + --disable-stats Disable statistics calculation/reporting + --enable-experimental-smallocx + Enable experimental smallocx API + --enable-prof Enable allocation profiling + --enable-prof-libunwind Use libunwind for backtracing + --disable-prof-libgcc Do not use libgcc for backtracing + --disable-prof-gcc Do not use gcc intrinsics for backtracing + --disable-fill Disable support for junk/zero filling + --enable-utrace Enable utrace(2)-based tracing + --enable-xmalloc Support xmalloc option + --disable-cache-oblivious + Disable support for cache-oblivious allocation + alignment + --enable-log Support debug logging + --enable-readlinkat Use readlinkat over readlink + --enable-opt-safety-checks + Perform certain low-overhead checks, even in opt + mode + --disable-libdl Do not use libdl + --disable-syscall Disable use of syscall(2) + --enable-lazy-lock Enable lazy locking (only lock when multi-threaded) + --disable-zone-allocator + Disable zone allocator for Darwin + --disable-initial-exec-tls + Disable the initial-exec tls model + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-xslroot= XSL stylesheet root path + --with-lg-vaddr= + Number of significant virtual address bits + --with-version=..--g + Version string + --with-rpath= Colon-separated rpath (ELF systems only) + --with-mangling= Mangle symbols in + --with-jemalloc-prefix= + Prefix to prepend to all public APIs + --without-export disable exporting jemalloc public APIs + --with-private-namespace= + Prefix to prepend to all library-private APIs + --with-install-suffix= + Suffix to append to all installed files + --with-malloc-conf= + config.malloc_conf options string + --with-static-libunwind= + Path to static libunwind library; use rather than + dynamically linking + --with-lg-quantum= + Base 2 log of minimum allocation alignment + --with-lg-page= + Base 2 log of system page size + --with-lg-hugepage= + Base 2 log of system huge page size + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.71 + +Copyright (C) 2021 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=$ac_mid; break +else $as_nop + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_lo=$ac_mid; break +else $as_nop + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done +else $as_nop + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_hi=$ac_mid +else $as_nop + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval (void) { return $2; } +static unsigned long int ulongval (void) { return $2; } +#include +#include +int +main (void) +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + echo >>conftest.val; read $3 &5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. */ + +#include +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main (void) +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.71. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +# Test code for whether the C++ compiler supports C++98 (global declarations) +ac_cxx_conftest_cxx98_globals=' +// Does the compiler advertise C++98 conformance? +#if !defined __cplusplus || __cplusplus < 199711L +# error "Compiler does not advertise C++98 conformance" +#endif + +// These inclusions are to reject old compilers that +// lack the unsuffixed header files. +#include +#include + +// and are *not* freestanding headers in C++98. +extern void assert (int); +namespace std { + extern int strcmp (const char *, const char *); +} + +// Namespaces, exceptions, and templates were all added after "C++ 2.0". +using std::exception; +using std::strcmp; + +namespace { + +void test_exception_syntax() +{ + try { + throw "test"; + } catch (const char *s) { + // Extra parentheses suppress a warning when building autoconf itself, + // due to lint rules shared with more typical C programs. + assert (!(strcmp) (s, "test")); + } +} + +template struct test_template +{ + T const val; + explicit test_template(T t) : val(t) {} + template T add(U u) { return static_cast(u) + val; } +}; + +} // anonymous namespace +' + +# Test code for whether the C++ compiler supports C++98 (body of main) +ac_cxx_conftest_cxx98_main=' + assert (argc); + assert (! argv[0]); +{ + test_exception_syntax (); + test_template tt (2.0); + assert (tt.add (4) == 6.0); + assert (true && !false); +} +' + +# Test code for whether the C++ compiler supports C++11 (global declarations) +ac_cxx_conftest_cxx11_globals=' +// Does the compiler advertise C++ 2011 conformance? +#if !defined __cplusplus || __cplusplus < 201103L +# error "Compiler does not advertise C++11 conformance" +#endif + +namespace cxx11test +{ + constexpr int get_val() { return 20; } + + struct testinit + { + int i; + double d; + }; + + class delegate + { + public: + delegate(int n) : n(n) {} + delegate(): delegate(2354) {} + + virtual int getval() { return this->n; }; + protected: + int n; + }; + + class overridden : public delegate + { + public: + overridden(int n): delegate(n) {} + virtual int getval() override final { return this->n * 2; } + }; + + class nocopy + { + public: + nocopy(int i): i(i) {} + nocopy() = default; + nocopy(const nocopy&) = delete; + nocopy & operator=(const nocopy&) = delete; + private: + int i; + }; + + // for testing lambda expressions + template Ret eval(Fn f, Ret v) + { + return f(v); + } + + // for testing variadic templates and trailing return types + template auto sum(V first) -> V + { + return first; + } + template auto sum(V first, Args... rest) -> V + { + return first + sum(rest...); + } +} +' + +# Test code for whether the C++ compiler supports C++11 (body of main) +ac_cxx_conftest_cxx11_main=' +{ + // Test auto and decltype + auto a1 = 6538; + auto a2 = 48573953.4; + auto a3 = "String literal"; + + int total = 0; + for (auto i = a3; *i; ++i) { total += *i; } + + decltype(a2) a4 = 34895.034; +} +{ + // Test constexpr + short sa[cxx11test::get_val()] = { 0 }; +} +{ + // Test initializer lists + cxx11test::testinit il = { 4323, 435234.23544 }; +} +{ + // Test range-based for + int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, + 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + for (auto &x : array) { x += 23; } +} +{ + // Test lambda expressions + using cxx11test::eval; + assert (eval ([](int x) { return x*2; }, 21) == 42); + double d = 2.0; + assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); + assert (d == 5.0); + assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); + assert (d == 5.0); +} +{ + // Test use of variadic templates + using cxx11test::sum; + auto a = sum(1); + auto b = sum(1, 2); + auto c = sum(1.0, 2.0, 3.0); +} +{ + // Test constructor delegation + cxx11test::delegate d1; + cxx11test::delegate d2(); + cxx11test::delegate d3(45); +} +{ + // Test override and final + cxx11test::overridden o1(55464); +} +{ + // Test nullptr + char *c = nullptr; +} +{ + // Test template brackets + test_template<::test_template> v(test_template(12)); +} +{ + // Unicode literals + char const *utf8 = u8"UTF-8 string \u2500"; + char16_t const *utf16 = u"UTF-8 string \u2500"; + char32_t const *utf32 = U"UTF-32 string \u2500"; +} +' + +# Test code for whether the C compiler supports C++11 (complete). +ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} +${ac_cxx_conftest_cxx11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + ${ac_cxx_conftest_cxx11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C++98 (complete). +ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" + +# Auxiliary files required by this configure script. +ac_aux_files="install-sh config.guess config.sub" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}/build-aux" + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + +CONFIGURE_CFLAGS= +SPECIFIED_CFLAGS="${CFLAGS}" + + + + + +CONFIGURE_CXXFLAGS= +SPECIFIED_CXXFLAGS="${CXXFLAGS}" + + + + + +CONFIG=`echo ${ac_configure_args} | sed -e 's#'"'"'\([^ ]*\)'"'"'#\1#g'` + + +rev=2 + + +srcroot=$srcdir +if test "x${srcroot}" = "x." ; then + srcroot="" +else + srcroot="${srcroot}/" +fi + +abs_srcroot="`cd \"${srcdir}\"; pwd`/" + + +objroot="" + +abs_objroot="`pwd`/" + + +if test "x$prefix" = "xNONE" ; then + prefix="/usr/local" +fi +if test "x$exec_prefix" = "xNONE" ; then + exec_prefix=$prefix +fi +PREFIX=$prefix + +BINDIR=`eval echo $bindir` +BINDIR=`eval echo $BINDIR` + +INCLUDEDIR=`eval echo $includedir` +INCLUDEDIR=`eval echo $INCLUDEDIR` + +LIBDIR=`eval echo $libdir` +LIBDIR=`eval echo $LIBDIR` + +DATADIR=`eval echo $datadir` +DATADIR=`eval echo $DATADIR` + +MANDIR=`eval echo $mandir` +MANDIR=`eval echo $MANDIR` + + +# Extract the first word of "xsltproc", so it can be a program name with args. +set dummy xsltproc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_XSLTPROC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $XSLTPROC in + [\\/]* | ?:[\\/]*) + ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_XSLTPROC="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_XSLTPROC" && ac_cv_path_XSLTPROC="false" + ;; +esac +fi +XSLTPROC=$ac_cv_path_XSLTPROC +if test -n "$XSLTPROC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5 +printf "%s\n" "$XSLTPROC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +if test -d "/usr/share/xml/docbook/stylesheet/docbook-xsl" ; then + DEFAULT_XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl" +elif test -d "/usr/share/sgml/docbook/xsl-stylesheets" ; then + DEFAULT_XSLROOT="/usr/share/sgml/docbook/xsl-stylesheets" +else + DEFAULT_XSLROOT="" +fi + +# Check whether --with-xslroot was given. +if test ${with_xslroot+y} +then : + withval=$with_xslroot; +if test "x$with_xslroot" = "xno" ; then + XSLROOT="${DEFAULT_XSLROOT}" +else + XSLROOT="${with_xslroot}" +fi + +else $as_nop + XSLROOT="${DEFAULT_XSLROOT}" + +fi + +if test "x$XSLTPROC" = "xfalse" ; then + XSLROOT="" +fi + + +CFLAGS=$CFLAGS + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion -version; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else $as_nop + ac_file='' +fi +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+y} +ac_save_CFLAGS=$CFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +else $as_nop + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +if test "x$GCC" != "xyes" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler is MSVC" >&5 +printf %s "checking whether compiler is MSVC... " >&6; } +if test ${je_cv_msvc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + +#ifndef _MSC_VER + int fail-1; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_msvc=yes +else $as_nop + je_cv_msvc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_msvc" >&5 +printf "%s\n" "$je_cv_msvc" >&6; } +fi + +je_cv_cray_prgenv_wrapper="" +if test "x${PE_ENV}" != "x" ; then + case "${CC}" in + CC|cc) + je_cv_cray_prgenv_wrapper="yes" + ;; + *) + ;; + esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler is cray" >&5 +printf %s "checking whether compiler is cray... " >&6; } +if test ${je_cv_cray+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + +#ifndef _CRAYC + int fail-1; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cray=yes +else $as_nop + je_cv_cray=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_cray" >&5 +printf "%s\n" "$je_cv_cray" >&6; } + +if test "x${je_cv_cray}" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether cray compiler version is 8.4" >&5 +printf %s "checking whether cray compiler version is 8.4... " >&6; } +if test ${je_cv_cray_84+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + +#if !(_RELEASE_MAJOR == 8 && _RELEASE_MINOR == 4) + int fail-1; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cray_84=yes +else $as_nop + je_cv_cray_84=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_cray_84" >&5 +printf "%s\n" "$je_cv_cray_84" >&6; } +fi + +if test "x$GCC" = "xyes" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -std=gnu11" >&5 +printf %s "checking whether compiler supports -std=gnu11... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-std=gnu11 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-std=gnu11 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + if test "x$je_cv_cflags_added" = "x-std=gnu11" ; then + printf "%s\n" "#define JEMALLOC_HAS_RESTRICT 1" >>confdefs.h + + else + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -std=gnu99" >&5 +printf %s "checking whether compiler supports -std=gnu99... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-std=gnu99 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-std=gnu99 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + if test "x$je_cv_cflags_added" = "x-std=gnu99" ; then + printf "%s\n" "#define JEMALLOC_HAS_RESTRICT 1" >>confdefs.h + + fi + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wall" >&5 +printf %s "checking whether compiler supports -Wall... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Wall + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Wall + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wextra" >&5 +printf %s "checking whether compiler supports -Wextra... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Wextra + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Wextra + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wshorten-64-to-32" >&5 +printf %s "checking whether compiler supports -Wshorten-64-to-32... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Wshorten-64-to-32 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Wshorten-64-to-32 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wsign-compare" >&5 +printf %s "checking whether compiler supports -Wsign-compare... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Wsign-compare + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Wsign-compare + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wundef" >&5 +printf %s "checking whether compiler supports -Wundef... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Wundef + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Wundef + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wno-format-zero-length" >&5 +printf %s "checking whether compiler supports -Wno-format-zero-length... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Wno-format-zero-length + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Wno-format-zero-length + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -pipe" >&5 +printf %s "checking whether compiler supports -pipe... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-pipe + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-pipe + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -g3" >&5 +printf %s "checking whether compiler supports -g3... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-g3 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-g3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +elif test "x$je_cv_msvc" = "xyes" ; then + CC="$CC -nologo" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Zi" >&5 +printf %s "checking whether compiler supports -Zi... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Zi + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Zi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -MT" >&5 +printf %s "checking whether compiler supports -MT... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-MT + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-MT + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -W3" >&5 +printf %s "checking whether compiler supports -W3... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-W3 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-W3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -FS" >&5 +printf %s "checking whether compiler supports -FS... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-FS + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-FS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + T_APPEND_V=-I${srcdir}/include/msvc_compat + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + +fi +if test "x$je_cv_cray" = "xyes" ; then + if test "x$je_cv_cray_84" = "xyes" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -hipa2" >&5 +printf %s "checking whether compiler supports -hipa2... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-hipa2 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-hipa2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -hnognu" >&5 +printf %s "checking whether compiler supports -hnognu... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-hnognu + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-hnognu + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -hnomessage=128" >&5 +printf %s "checking whether compiler supports -hnomessage=128... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-hnomessage=128 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-hnomessage=128 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -hnomessage=1357" >&5 +printf %s "checking whether compiler supports -hnomessage=1357... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-hnomessage=1357 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-hnomessage=1357 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test ${ac_cv_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +printf "%s\n" "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Check whether --enable-cxx was given. +if test ${enable_cxx+y} +then : + enableval=$enable_cxx; if test "x$enable_cxx" = "xno" ; then + enable_cxx="0" +else + enable_cxx="1" +fi + +else $as_nop + enable_cxx="1" + +fi + +if test "x$enable_cxx" = "x1" ; then + # =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 4 + + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 +printf %s "checking whether the compiler supports GNU C++... " >&6; } +if test ${ac_cv_cxx_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_compiler_gnu=yes +else $as_nop + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+y} +ac_save_CXXFLAGS=$CXXFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +printf %s "checking whether $CXX accepts -g... " >&6; } +if test ${ac_cv_prog_cxx_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_g=yes +else $as_nop + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + +else $as_nop + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } +if test $ac_test_CXXFLAGS; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_prog_cxx_stdcxx=no +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 +printf %s "checking for $CXX option to enable C++11 features... " >&6; } +if test ${ac_cv_prog_cxx_11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_11=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx11_program +_ACEOF +for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx11" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx11" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_prog_cxx_stdcxx=cxx11 +fi +fi +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 +printf %s "checking for $CXX option to enable C++98 features... " >&6; } +if test ${ac_cv_prog_cxx_98+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_98=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx98_program +_ACEOF +for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx98=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx98" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx98" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx98" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx98" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 + ac_prog_cxx_stdcxx=cxx98 +fi +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + ax_cxx_compile_cxx14_required=false + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features by default" >&5 +printf %s "checking whether $CXX supports C++14 features by default... " >&6; } +if test ${ax_cv_cxx_compile_cxx14+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + ax_cv_cxx_compile_cxx14=yes +else $as_nop + ax_cv_cxx_compile_cxx14=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx14" >&5 +printf "%s\n" "$ax_cv_cxx_compile_cxx14" >&6; } + if test x$ax_cv_cxx_compile_cxx14 = xyes; then + ac_success=yes + fi + + + + if test x$ac_success = xno; then + for switch in -std=c++14 -std=c++0x +std=c++14 "-h std=c++14"; do + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5 +printf %s "checking whether $CXX supports C++14 features with $switch... " >&6; } +if eval test \${$cachevar+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + eval $cachevar=yes +else $as_nop + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx14_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX14=0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5 +printf "%s\n" "$as_me: No compiler with C++14 support was found" >&6;} + else + HAVE_CXX14=1 + +printf "%s\n" "#define HAVE_CXX14 1" >>confdefs.h + + fi + + + if test "x${HAVE_CXX14}" = "x1" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wall" >&5 +printf %s "checking whether compiler supports -Wall... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-Wall + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-Wall + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wextra" >&5 +printf %s "checking whether compiler supports -Wextra... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-Wextra + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-Wextra + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -g3" >&5 +printf %s "checking whether compiler supports -g3... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-g3 + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-g3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + + SAVED_LIBS="${LIBS}" + T_APPEND_V=-lstdc++ + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether libstdc++ linkage is compilable" >&5 +printf %s "checking whether libstdc++ linkage is compilable... " >&6; } +if test ${je_cv_libstdcxx+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + int *arr = (int *)malloc(sizeof(int) * 42); + if (arr == NULL) + return 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_libstdcxx=yes +else $as_nop + je_cv_libstdcxx=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_libstdcxx" >&5 +printf "%s\n" "$je_cv_libstdcxx" >&6; } + + if test "x${je_cv_libstdcxx}" = "xno" ; then + LIBS="${SAVED_LIBS}" + fi + else + enable_cxx="0" + fi +fi + + + + + +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi +done + + + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + +fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +printf %s "checking whether byte ordering is bigendian... " >&6; } +if test ${ac_cv_c_bigendian+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main (void) +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main (void) +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_bigendian=yes +else $as_nop + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main (void) +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main (void) +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_bigendian=yes +else $as_nop + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes +then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +unsigned short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + unsigned short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + unsigned short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + unsigned short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main (void) +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main (void) +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_c_bigendian=no +else $as_nop + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +printf "%s\n" "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + ac_cv_big_endian=1;; #( + no) + ac_cv_big_endian=0 ;; #( + universal) + +printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +if test "x${ac_cv_big_endian}" = "x1" ; then + printf "%s\n" "#define JEMALLOC_BIG_ENDIAN " >>confdefs.h + +fi + +if test "x${je_cv_msvc}" = "xyes" -a "x${ac_cv_header_inttypes_h}" = "xno"; then + T_APPEND_V=-I${srcdir}/include/msvc_compat/C99 + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + +fi + +if test "x${je_cv_msvc}" = "xyes" ; then + LG_SIZEOF_PTR=LG_SIZEOF_PTR_WIN + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using a predefined value for sizeof(void *): 4 for 32-bit, 8 for 64-bit" >&5 +printf "%s\n" "Using a predefined value for sizeof(void *): 4 for 32-bit, 8 for 64-bit" >&6; } +else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +printf %s "checking size of void *... " >&6; } +if test ${ac_cv_sizeof_void_p+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_void_p" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +printf "%s\n" "$ac_cv_sizeof_void_p" >&6; } + + + +printf "%s\n" "#define SIZEOF_VOID_P $ac_cv_sizeof_void_p" >>confdefs.h + + + if test "x${ac_cv_sizeof_void_p}" = "x8" ; then + LG_SIZEOF_PTR=3 + elif test "x${ac_cv_sizeof_void_p}" = "x4" ; then + LG_SIZEOF_PTR=2 + else + as_fn_error $? "Unsupported pointer size: ${ac_cv_sizeof_void_p}" "$LINENO" 5 + fi +fi +printf "%s\n" "#define LG_SIZEOF_PTR $LG_SIZEOF_PTR" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +printf %s "checking size of int... " >&6; } +if test ${ac_cv_sizeof_int+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_int" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +printf "%s\n" "$ac_cv_sizeof_int" >&6; } + + + +printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h + + +if test "x${ac_cv_sizeof_int}" = "x8" ; then + LG_SIZEOF_INT=3 +elif test "x${ac_cv_sizeof_int}" = "x4" ; then + LG_SIZEOF_INT=2 +else + as_fn_error $? "Unsupported int size: ${ac_cv_sizeof_int}" "$LINENO" 5 +fi +printf "%s\n" "#define LG_SIZEOF_INT $LG_SIZEOF_INT" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +printf %s "checking size of long... " >&6; } +if test ${ac_cv_sizeof_long+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_long" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long" >&6; } + + + +printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h + + +if test "x${ac_cv_sizeof_long}" = "x8" ; then + LG_SIZEOF_LONG=3 +elif test "x${ac_cv_sizeof_long}" = "x4" ; then + LG_SIZEOF_LONG=2 +else + as_fn_error $? "Unsupported long size: ${ac_cv_sizeof_long}" "$LINENO" 5 +fi +printf "%s\n" "#define LG_SIZEOF_LONG $LG_SIZEOF_LONG" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +printf %s "checking size of long long... " >&6; } +if test ${ac_cv_sizeof_long_long+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_long_long" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_long=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long_long" >&6; } + + + +printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h + + +if test "x${ac_cv_sizeof_long_long}" = "x8" ; then + LG_SIZEOF_LONG_LONG=3 +elif test "x${ac_cv_sizeof_long_long}" = "x4" ; then + LG_SIZEOF_LONG_LONG=2 +else + as_fn_error $? "Unsupported long long size: ${ac_cv_sizeof_long_long}" "$LINENO" 5 +fi +printf "%s\n" "#define LG_SIZEOF_LONG_LONG $LG_SIZEOF_LONG_LONG" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of intmax_t" >&5 +printf %s "checking size of intmax_t... " >&6; } +if test ${ac_cv_sizeof_intmax_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (intmax_t))" "ac_cv_sizeof_intmax_t" "$ac_includes_default" +then : + +else $as_nop + if test "$ac_cv_type_intmax_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (intmax_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_intmax_t=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_intmax_t" >&5 +printf "%s\n" "$ac_cv_sizeof_intmax_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t" >>confdefs.h + + +if test "x${ac_cv_sizeof_intmax_t}" = "x16" ; then + LG_SIZEOF_INTMAX_T=4 +elif test "x${ac_cv_sizeof_intmax_t}" = "x8" ; then + LG_SIZEOF_INTMAX_T=3 +elif test "x${ac_cv_sizeof_intmax_t}" = "x4" ; then + LG_SIZEOF_INTMAX_T=2 +else + as_fn_error $? "Unsupported intmax_t size: ${ac_cv_sizeof_intmax_t}" "$LINENO" 5 +fi +printf "%s\n" "#define LG_SIZEOF_INTMAX_T $LG_SIZEOF_INTMAX_T" >>confdefs.h + + + + + + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +CPU_SPINWAIT="" +case "${host_cpu}" in + i686|x86_64) + HAVE_CPU_SPINWAIT=1 + if test "x${je_cv_msvc}" = "xyes" ; then + if test ${je_cv_pause_msvc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pause instruction MSVC is compilable" >&5 +printf %s "checking whether pause instruction MSVC is compilable... " >&6; } +if test ${je_cv_pause_msvc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +_mm_pause(); return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_pause_msvc=yes +else $as_nop + je_cv_pause_msvc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_pause_msvc" >&5 +printf "%s\n" "$je_cv_pause_msvc" >&6; } + +fi + + if test "x${je_cv_pause_msvc}" = "xyes" ; then + CPU_SPINWAIT='_mm_pause()' + fi + else + if test ${je_cv_pause+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pause instruction is compilable" >&5 +printf %s "checking whether pause instruction is compilable... " >&6; } +if test ${je_cv_pause+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +__asm__ volatile("pause"); return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_pause=yes +else $as_nop + je_cv_pause=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_pause" >&5 +printf "%s\n" "$je_cv_pause" >&6; } + +fi + + if test "x${je_cv_pause}" = "xyes" ; then + CPU_SPINWAIT='__asm__ volatile("pause")' + fi + fi + ;; + *) + HAVE_CPU_SPINWAIT=0 + ;; +esac +printf "%s\n" "#define HAVE_CPU_SPINWAIT $HAVE_CPU_SPINWAIT" >>confdefs.h + +printf "%s\n" "#define CPU_SPINWAIT $CPU_SPINWAIT" >>confdefs.h + + + +# Check whether --with-lg_vaddr was given. +if test ${with_lg_vaddr+y} +then : + withval=$with_lg_vaddr; LG_VADDR="$with_lg_vaddr" +else $as_nop + LG_VADDR="detect" +fi + + +case "${host_cpu}" in + aarch64) + if test "x$LG_VADDR" = "xdetect"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking number of significant virtual address bits" >&5 +printf %s "checking number of significant virtual address bits... " >&6; } + if test "x${LG_SIZEOF_PTR}" = "x2" ; then + #aarch64 ILP32 + LG_VADDR=32 + else + #aarch64 LP64 + LG_VADDR=48 + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LG_VADDR" >&5 +printf "%s\n" "$LG_VADDR" >&6; } + fi + ;; + x86_64) + if test "x$LG_VADDR" = "xdetect"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking number of significant virtual address bits" >&5 +printf %s "checking number of significant virtual address bits... " >&6; } +if test ${je_cv_lg_vaddr+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + je_cv_lg_vaddr=57 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef _WIN32 +#include +#include +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +int +main (void) +{ + + uint32_t r[4]; + uint32_t eax_in = 0x80000008U; +#ifdef _WIN32 + __cpuid((int *)r, (int)eax_in); +#else + asm volatile ("cpuid" + : "=a" (r[0]), "=b" (r[1]), "=c" (r[2]), "=d" (r[3]) + : "a" (eax_in), "c" (0) + ); +#endif + uint32_t eax_out = r[0]; + uint32_t vaddr = ((eax_out & 0x0000ff00U) >> 8); + FILE *f = fopen("conftest.out", "w"); + if (f == NULL) { + return 1; + } + if (vaddr > (sizeof(void *) << 3)) { + vaddr = sizeof(void *) << 3; + } + fprintf(f, "%u", vaddr); + fclose(f); + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + je_cv_lg_vaddr=`cat conftest.out` +else $as_nop + je_cv_lg_vaddr=error +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_lg_vaddr" >&5 +printf "%s\n" "$je_cv_lg_vaddr" >&6; } + if test "x${je_cv_lg_vaddr}" != "x" ; then + LG_VADDR="${je_cv_lg_vaddr}" + fi + if test "x${LG_VADDR}" != "xerror" ; then + printf "%s\n" "#define LG_VADDR $LG_VADDR" >>confdefs.h + + else + as_fn_error $? "cannot determine number of significant virtual address bits" "$LINENO" 5 + fi + fi + ;; + *) + if test "x$LG_VADDR" = "xdetect"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking number of significant virtual address bits" >&5 +printf %s "checking number of significant virtual address bits... " >&6; } + if test "x${LG_SIZEOF_PTR}" = "x3" ; then + LG_VADDR=64 + elif test "x${LG_SIZEOF_PTR}" = "x2" ; then + LG_VADDR=32 + elif test "x${LG_SIZEOF_PTR}" = "xLG_SIZEOF_PTR_WIN" ; then + LG_VADDR="(1U << (LG_SIZEOF_PTR_WIN+3))" + else + as_fn_error $? "Unsupported lg(pointer size): ${LG_SIZEOF_PTR}" "$LINENO" 5 + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LG_VADDR" >&5 +printf "%s\n" "$LG_VADDR" >&6; } + fi + ;; +esac +printf "%s\n" "#define LG_VADDR $LG_VADDR" >>confdefs.h + + +LD_PRELOAD_VAR="LD_PRELOAD" +so="so" +importlib="${so}" +o="$ac_objext" +a="a" +exe="$ac_exeext" +libprefix="lib" +link_whole_archive="0" +DSO_LDFLAGS='-shared -Wl,-soname,$(@F)' +RPATH='-Wl,-rpath,$(1)' +SOREV="${so}.${rev}" +PIC_CFLAGS='-fPIC -DPIC' +CTARGET='-o $@' +LDTARGET='-o $@' +TEST_LD_MODE= +EXTRA_LDFLAGS= +ARFLAGS='crus' +AROUT=' $@' +CC_MM=1 + +if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then + TEST_LD_MODE='-dynamic' +fi + +if test "x${je_cv_cray}" = "xyes" ; then + CC_MM= +fi + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_NM+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NM" >&5 +printf "%s\n" "$NM" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_NM+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NM="nm" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5 +printf "%s\n" "$ac_ct_NM" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +else + NM="$ac_cv_prog_NM" +fi + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + + +# Check whether --with-version was given. +if test ${with_version+y} +then : + withval=$with_version; + echo "${with_version}" | grep '^[0-9]\+\.[0-9]\+\.[0-9]\+-[0-9]\+-g[0-9a-f]\+$' 2>&1 1>/dev/null + if test $? -eq 0 ; then + echo "$with_version" > "${objroot}VERSION" + else + echo "${with_version}" | grep '^VERSION$' 2>&1 1>/dev/null + if test $? -ne 0 ; then + as_fn_error $? "${with_version} does not match ..--g or VERSION" "$LINENO" 5 + fi + fi + +else $as_nop + + if test "x`test ! \"${srcroot}\" && cd \"${srcroot}\"; git rev-parse --is-inside-work-tree 2>/dev/null`" = "xtrue" ; then + for pattern in '[0-9].[0-9].[0-9]' '[0-9].[0-9].[0-9][0-9]' \ + '[0-9].[0-9][0-9].[0-9]' '[0-9].[0-9][0-9].[0-9][0-9]' \ + '[0-9][0-9].[0-9].[0-9]' '[0-9][0-9].[0-9].[0-9][0-9]' \ + '[0-9][0-9].[0-9][0-9].[0-9]' \ + '[0-9][0-9].[0-9][0-9].[0-9][0-9]'; do + (test ! "${srcroot}" && cd "${srcroot}"; git describe --long --abbrev=40 --match="${pattern}") > "${objroot}VERSION.tmp" 2>/dev/null + if test $? -eq 0 ; then + mv "${objroot}VERSION.tmp" "${objroot}VERSION" + break + fi + done + fi + rm -f "${objroot}VERSION.tmp" + +fi + + +if test ! -e "${objroot}VERSION" ; then + if test ! -e "${srcroot}VERSION" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Missing VERSION file, and unable to generate it; creating bogus VERSION" >&5 +printf "%s\n" "Missing VERSION file, and unable to generate it; creating bogus VERSION" >&6; } + echo "0.0.0-0-g0000000000000000000000000000000000000000" > "${objroot}VERSION" + else + cp ${srcroot}VERSION ${objroot}VERSION + fi +fi +jemalloc_version=`cat "${objroot}VERSION"` +jemalloc_version_major=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print $1}'` +jemalloc_version_minor=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print $2}'` +jemalloc_version_bugfix=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print $3}'` +jemalloc_version_nrev=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print $4}'` +jemalloc_version_gid=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print $5}'` + + + + + + + +default_retain="0" +maps_coalesce="1" +DUMP_SYMS="${NM} -a" +SYM_PREFIX="" +case "${host}" in + *-*-darwin* | *-*-ios*) + abi="macho" + RPATH="" + LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" + so="dylib" + importlib="${so}" + force_tls="0" + DSO_LDFLAGS='-shared -Wl,-install_name,$(LIBDIR)/$(@F)' + SOREV="${rev}.${so}" + sbrk_deprecated="1" + SYM_PREFIX="_" + ;; + *-*-freebsd*) + abi="elf" + printf "%s\n" "#define JEMALLOC_SYSCTL_VM_OVERCOMMIT " >>confdefs.h + + force_lazy_lock="1" + ;; + *-*-dragonfly*) + abi="elf" + ;; + *-*-openbsd*) + abi="elf" + force_tls="0" + ;; + *-*-bitrig*) + abi="elf" + ;; + *-*-linux-android) + T_APPEND_V=-D_GNU_SOURCE + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + + abi="elf" + printf "%s\n" "#define JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_HAS_ALLOCA_H 1" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_THREADED_INIT " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_C11_ATOMICS 1" >>confdefs.h + + force_tls="0" + if test "${LG_SIZEOF_PTR}" = "3"; then + default_retain="1" + fi + ;; + *-*-linux*) + T_APPEND_V=-D_GNU_SOURCE + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + + abi="elf" + printf "%s\n" "#define JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_HAS_ALLOCA_H 1" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_THREADED_INIT " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_USE_CXX_THROW " >>confdefs.h + + if test "${LG_SIZEOF_PTR}" = "3"; then + default_retain="1" + fi + ;; + *-*-kfreebsd*) + T_APPEND_V=-D_GNU_SOURCE + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + + abi="elf" + printf "%s\n" "#define JEMALLOC_HAS_ALLOCA_H 1" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_SYSCTL_VM_OVERCOMMIT " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_THREADED_INIT " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_USE_CXX_THROW " >>confdefs.h + + ;; + *-*-netbsd*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ABI" >&5 +printf %s "checking ABI... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __ELF__ +/* ELF */ +#else +#error aout +#endif + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + abi="elf" +else $as_nop + abi="aout" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $abi" >&5 +printf "%s\n" "$abi" >&6; } + ;; + *-*-solaris2*) + abi="elf" + RPATH='-Wl,-R,$(1)' + T_APPEND_V=-D_POSIX_PTHREAD_SEMANTICS + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + + T_APPEND_V=-lposix4 -lsocket -lnsl + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + + ;; + *-ibm-aix*) + if test "${LG_SIZEOF_PTR}" = "3"; then + LD_PRELOAD_VAR="LDR_PRELOAD64" + else + LD_PRELOAD_VAR="LDR_PRELOAD" + fi + abi="xcoff" + ;; + *-*-mingw* | *-*-cygwin*) + abi="pecoff" + force_tls="0" + maps_coalesce="0" + RPATH="" + so="dll" + if test "x$je_cv_msvc" = "xyes" ; then + importlib="lib" + DSO_LDFLAGS="-LD" + EXTRA_LDFLAGS="-link -DEBUG" + CTARGET='-Fo$@' + LDTARGET='-Fe$@' + AR='lib' + ARFLAGS='-nologo -out:' + AROUT='$@' + CC_MM= + else + importlib="${so}" + DSO_LDFLAGS="-shared" + link_whole_archive="1" + fi + case "${host}" in + *-*-cygwin*) + DUMP_SYMS="dumpbin /SYMBOLS" + ;; + *) + ;; + esac + a="lib" + libprefix="" + SOREV="${so}" + PIC_CFLAGS="" + if test "${LG_SIZEOF_PTR}" = "3"; then + default_retain="1" + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Unsupported operating system: ${host}" >&5 +printf "%s\n" "Unsupported operating system: ${host}" >&6; } + abi="elf" + ;; +esac + +JEMALLOC_USABLE_SIZE_CONST=const + for ac_header in malloc.h +do : + ac_fn_c_check_header_compile "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default" +if test "x$ac_cv_header_malloc_h" = xyes +then : + printf "%s\n" "#define HAVE_MALLOC_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether malloc_usable_size definition can use const argument" >&5 +printf %s "checking whether malloc_usable_size definition can use const argument... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + size_t malloc_usable_size(const void *ptr); + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else $as_nop + + JEMALLOC_USABLE_SIZE_CONST= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi + +done +printf "%s\n" "#define JEMALLOC_USABLE_SIZE_CONST $JEMALLOC_USABLE_SIZE_CONST" >>confdefs.h + + + + + + + + + + + + + + + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 +printf %s "checking for library containing log... " >&6; } +if test ${ac_cv_search_log+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char log (); +int +main (void) +{ +return log (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_log=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_log+y} +then : + break +fi +done +if test ${ac_cv_search_log+y} +then : + +else $as_nop + ac_cv_search_log=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5 +printf "%s\n" "$ac_cv_search_log" >&6; } +ac_res=$ac_cv_search_log +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else $as_nop + as_fn_error $? "Missing math functions" "$LINENO" 5 +fi + +if test "x$ac_cv_search_log" != "xnone required" ; then + LM="$ac_cv_search_log" +else + LM= +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether __attribute__ syntax is compilable" >&5 +printf %s "checking whether __attribute__ syntax is compilable... " >&6; } +if test ${je_cv_attribute+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +static __attribute__((unused)) void foo(void){} +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_attribute=yes +else $as_nop + je_cv_attribute=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_attribute" >&5 +printf "%s\n" "$je_cv_attribute" >&6; } + +if test "x${je_cv_attribute}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_ATTR " >>confdefs.h + + if test "x${GCC}" = "xyes" -a "x${abi}" = "xelf"; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -fvisibility=hidden" >&5 +printf %s "checking whether compiler supports -fvisibility=hidden... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-fvisibility=hidden + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-fvisibility=hidden + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -fvisibility=hidden" >&5 +printf %s "checking whether compiler supports -fvisibility=hidden... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-fvisibility=hidden + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-fvisibility=hidden + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + fi +fi +SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -herror_on_warning" >&5 +printf %s "checking whether compiler supports -herror_on_warning... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-herror_on_warning + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-herror_on_warning + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether tls_model attribute is compilable" >&5 +printf %s "checking whether tls_model attribute is compilable... " >&6; } +if test ${je_cv_tls_model+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +static __thread int + __attribute__((tls_model("initial-exec"), unused)) foo; + foo = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_tls_model=yes +else $as_nop + je_cv_tls_model=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_tls_model" >&5 +printf "%s\n" "$je_cv_tls_model" >&6; } + +CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -herror_on_warning" >&5 +printf %s "checking whether compiler supports -herror_on_warning... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-herror_on_warning + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-herror_on_warning + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether alloc_size attribute is compilable" >&5 +printf %s "checking whether alloc_size attribute is compilable... " >&6; } +if test ${je_cv_alloc_size+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *foo(size_t size) __attribute__((alloc_size(1))); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_alloc_size=yes +else $as_nop + je_cv_alloc_size=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_alloc_size" >&5 +printf "%s\n" "$je_cv_alloc_size" >&6; } + +CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +if test "x${je_cv_alloc_size}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_ATTR_ALLOC_SIZE " >>confdefs.h + +fi +SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -herror_on_warning" >&5 +printf %s "checking whether compiler supports -herror_on_warning... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-herror_on_warning + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-herror_on_warning + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether format(gnu_printf, ...) attribute is compilable" >&5 +printf %s "checking whether format(gnu_printf, ...) attribute is compilable... " >&6; } +if test ${je_cv_format_gnu_printf+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *foo(const char *format, ...) __attribute__((format(gnu_printf, 1, 2))); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_format_gnu_printf=yes +else $as_nop + je_cv_format_gnu_printf=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_format_gnu_printf" >&5 +printf "%s\n" "$je_cv_format_gnu_printf" >&6; } + +CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +if test "x${je_cv_format_gnu_printf}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF " >>confdefs.h + +fi +SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -herror_on_warning" >&5 +printf %s "checking whether compiler supports -herror_on_warning... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-herror_on_warning + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-herror_on_warning + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether format(printf, ...) attribute is compilable" >&5 +printf %s "checking whether format(printf, ...) attribute is compilable... " >&6; } +if test ${je_cv_format_printf+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *foo(const char *format, ...) __attribute__((format(printf, 1, 2))); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_format_printf=yes +else $as_nop + je_cv_format_printf=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_format_printf" >&5 +printf "%s\n" "$je_cv_format_printf" >&6; } + +CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +if test "x${je_cv_format_printf}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_ATTR_FORMAT_PRINTF " >>confdefs.h + +fi + +SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -herror_on_warning" >&5 +printf %s "checking whether compiler supports -herror_on_warning... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-herror_on_warning + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-herror_on_warning + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether format(printf, ...) attribute is compilable" >&5 +printf %s "checking whether format(printf, ...) attribute is compilable... " >&6; } +if test ${je_cv_format_arg+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +const char * __attribute__((__format_arg__(1))) foo(const char *format); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_format_arg=yes +else $as_nop + je_cv_format_arg=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_format_arg" >&5 +printf "%s\n" "$je_cv_format_arg" >&6; } + +CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +if test "x${je_cv_format_arg}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_ATTR_FORMAT_ARG " >>confdefs.h + +fi + + +# Check whether --with-rpath was given. +if test ${with_rpath+y} +then : + withval=$with_rpath; if test "x$with_rpath" = "xno" ; then + RPATH_EXTRA= +else + RPATH_EXTRA="`echo $with_rpath | tr \":\" \" \"`" +fi +else $as_nop + RPATH_EXTRA= + +fi + + + +# Check whether --enable-autogen was given. +if test ${enable_autogen+y} +then : + enableval=$enable_autogen; if test "x$enable_autogen" = "xno" ; then + enable_autogen="0" +else + enable_autogen="1" +fi + +else $as_nop + enable_autogen="0" + +fi + + + + + # Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test ${ac_cv_path_install+y}; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# Extract the first word of "ld", so it can be a program name with args. +set dummy ld; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $LD in + [\\/]* | ?:[\\/]*) + ac_cv_path_LD="$LD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LD="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LD" && ac_cv_path_LD="false" + ;; +esac +fi +LD=$ac_cv_path_LD +if test -n "$LD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +printf "%s\n" "$LD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +# Extract the first word of "autoconf", so it can be a program name with args. +set dummy autoconf; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_AUTOCONF+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $AUTOCONF in + [\\/]* | ?:[\\/]*) + ac_cv_path_AUTOCONF="$AUTOCONF" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_AUTOCONF="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_AUTOCONF" && ac_cv_path_AUTOCONF="false" + ;; +esac +fi +AUTOCONF=$ac_cv_path_AUTOCONF +if test -n "$AUTOCONF"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AUTOCONF" >&5 +printf "%s\n" "$AUTOCONF" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + +# Check whether --enable-doc was given. +if test ${enable_doc+y} +then : + enableval=$enable_doc; if test "x$enable_doc" = "xno" ; then + enable_doc="0" +else + enable_doc="1" +fi + +else $as_nop + enable_doc="1" + +fi + + + +# Check whether --enable-shared was given. +if test ${enable_shared+y} +then : + enableval=$enable_shared; if test "x$enable_shared" = "xno" ; then + enable_shared="0" +else + enable_shared="1" +fi + +else $as_nop + enable_shared="1" + +fi + + + +# Check whether --enable-static was given. +if test ${enable_static+y} +then : + enableval=$enable_static; if test "x$enable_static" = "xno" ; then + enable_static="0" +else + enable_static="1" +fi + +else $as_nop + enable_static="1" + +fi + + + +if test "$enable_shared$enable_static" = "00" ; then + as_fn_error $? "Please enable one of shared or static builds" "$LINENO" 5 +fi + + +# Check whether --with-mangling was given. +if test ${with_mangling+y} +then : + withval=$with_mangling; mangling_map="$with_mangling" +else $as_nop + mangling_map="" +fi + + + +# Check whether --with-jemalloc_prefix was given. +if test ${with_jemalloc_prefix+y} +then : + withval=$with_jemalloc_prefix; JEMALLOC_PREFIX="$with_jemalloc_prefix" +else $as_nop + if test "x$abi" != "xmacho" -a "x$abi" != "xpecoff"; then + JEMALLOC_PREFIX="" +else + JEMALLOC_PREFIX="je_" +fi + +fi + +if test "x$JEMALLOC_PREFIX" = "x" ; then + printf "%s\n" "#define JEMALLOC_IS_MALLOC 1" >>confdefs.h + +else + JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"` + printf "%s\n" "#define JEMALLOC_PREFIX \"$JEMALLOC_PREFIX\"" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_CPREFIX \"$JEMALLOC_CPREFIX\"" >>confdefs.h + +fi + + + + +# Check whether --with-export was given. +if test ${with_export+y} +then : + withval=$with_export; if test "x$with_export" = "xno"; then + printf "%s\n" "#define JEMALLOC_EXPORT /**/" >>confdefs.h + +fi + +fi + + +public_syms="aligned_alloc calloc dallocx free mallctl mallctlbymib mallctlnametomib malloc malloc_conf malloc_message malloc_stats_print malloc_usable_size mallocx smallocx_${jemalloc_version_gid} nallocx posix_memalign rallocx realloc sallocx sdallocx xallocx" +ac_fn_c_check_func "$LINENO" "memalign" "ac_cv_func_memalign" +if test "x$ac_cv_func_memalign" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE_MEMALIGN " >>confdefs.h + + public_syms="${public_syms} memalign" +fi + +ac_fn_c_check_func "$LINENO" "valloc" "ac_cv_func_valloc" +if test "x$ac_cv_func_valloc" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE_VALLOC " >>confdefs.h + + public_syms="${public_syms} valloc" +fi + + +wrap_syms= +if test "x${JEMALLOC_PREFIX}" = "x" ; then + ac_fn_c_check_func "$LINENO" "__libc_calloc" "ac_cv_func___libc_calloc" +if test "x$ac_cv_func___libc_calloc" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___LIBC_CALLOC " >>confdefs.h + + wrap_syms="${wrap_syms} __libc_calloc" +fi + + ac_fn_c_check_func "$LINENO" "__libc_free" "ac_cv_func___libc_free" +if test "x$ac_cv_func___libc_free" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___LIBC_FREE " >>confdefs.h + + wrap_syms="${wrap_syms} __libc_free" +fi + + ac_fn_c_check_func "$LINENO" "__libc_malloc" "ac_cv_func___libc_malloc" +if test "x$ac_cv_func___libc_malloc" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___LIBC_MALLOC " >>confdefs.h + + wrap_syms="${wrap_syms} __libc_malloc" +fi + + ac_fn_c_check_func "$LINENO" "__libc_memalign" "ac_cv_func___libc_memalign" +if test "x$ac_cv_func___libc_memalign" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___LIBC_MEMALIGN " >>confdefs.h + + wrap_syms="${wrap_syms} __libc_memalign" +fi + + ac_fn_c_check_func "$LINENO" "__libc_realloc" "ac_cv_func___libc_realloc" +if test "x$ac_cv_func___libc_realloc" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___LIBC_REALLOC " >>confdefs.h + + wrap_syms="${wrap_syms} __libc_realloc" +fi + + ac_fn_c_check_func "$LINENO" "__libc_valloc" "ac_cv_func___libc_valloc" +if test "x$ac_cv_func___libc_valloc" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___LIBC_VALLOC " >>confdefs.h + + wrap_syms="${wrap_syms} __libc_valloc" +fi + + ac_fn_c_check_func "$LINENO" "__posix_memalign" "ac_cv_func___posix_memalign" +if test "x$ac_cv_func___posix_memalign" = xyes +then : + printf "%s\n" "#define JEMALLOC_OVERRIDE___POSIX_MEMALIGN " >>confdefs.h + + wrap_syms="${wrap_syms} __posix_memalign" +fi + +fi + +case "${host}" in + *-*-mingw* | *-*-cygwin*) + wrap_syms="${wrap_syms} tls_callback" + ;; + *) + ;; +esac + + +# Check whether --with-private_namespace was given. +if test ${with_private_namespace+y} +then : + withval=$with_private_namespace; JEMALLOC_PRIVATE_NAMESPACE="${with_private_namespace}je_" +else $as_nop + JEMALLOC_PRIVATE_NAMESPACE="je_" + +fi + +printf "%s\n" "#define JEMALLOC_PRIVATE_NAMESPACE $JEMALLOC_PRIVATE_NAMESPACE" >>confdefs.h + +private_namespace="$JEMALLOC_PRIVATE_NAMESPACE" + + + +# Check whether --with-install_suffix was given. +if test ${with_install_suffix+y} +then : + withval=$with_install_suffix; INSTALL_SUFFIX="$with_install_suffix" +else $as_nop + INSTALL_SUFFIX= + +fi + +install_suffix="$INSTALL_SUFFIX" + + + +# Check whether --with-malloc_conf was given. +if test ${with_malloc_conf+y} +then : + withval=$with_malloc_conf; JEMALLOC_CONFIG_MALLOC_CONF="$with_malloc_conf" +else $as_nop + JEMALLOC_CONFIG_MALLOC_CONF="" + +fi + +config_malloc_conf="$JEMALLOC_CONFIG_MALLOC_CONF" +printf "%s\n" "#define JEMALLOC_CONFIG_MALLOC_CONF \"$config_malloc_conf\"" >>confdefs.h + + +je_="je_" + + +cfgoutputs_in="Makefile.in" +cfgoutputs_in="${cfgoutputs_in} jemalloc.pc.in" +cfgoutputs_in="${cfgoutputs_in} doc/html.xsl.in" +cfgoutputs_in="${cfgoutputs_in} doc/manpages.xsl.in" +cfgoutputs_in="${cfgoutputs_in} doc/jemalloc.xml.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_macros.h.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_protos.h.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_typedefs.h.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/internal/jemalloc_preamble.h.in" +cfgoutputs_in="${cfgoutputs_in} test/test.sh.in" +cfgoutputs_in="${cfgoutputs_in} test/include/test/jemalloc_test.h.in" + +cfgoutputs_out="Makefile" +cfgoutputs_out="${cfgoutputs_out} jemalloc.pc" +cfgoutputs_out="${cfgoutputs_out} doc/html.xsl" +cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl" +cfgoutputs_out="${cfgoutputs_out} doc/jemalloc.xml" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_macros.h" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_protos.h" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_typedefs.h" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_preamble.h" +cfgoutputs_out="${cfgoutputs_out} test/test.sh" +cfgoutputs_out="${cfgoutputs_out} test/include/test/jemalloc_test.h" + +cfgoutputs_tup="Makefile" +cfgoutputs_tup="${cfgoutputs_tup} jemalloc.pc:jemalloc.pc.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc.xml:doc/jemalloc.xml.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_macros.h:include/jemalloc/jemalloc_macros.h.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_protos.h:include/jemalloc/jemalloc_protos.h.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_typedefs.h:include/jemalloc/jemalloc_typedefs.h.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_preamble.h" +cfgoutputs_tup="${cfgoutputs_tup} test/test.sh:test/test.sh.in" +cfgoutputs_tup="${cfgoutputs_tup} test/include/test/jemalloc_test.h:test/include/test/jemalloc_test.h.in" + +cfghdrs_in="include/jemalloc/jemalloc_defs.h.in" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/jemalloc_internal_defs.h.in" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_symbols.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_namespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_namespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_unnamespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_rename.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_mangle.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc.sh" +cfghdrs_in="${cfghdrs_in} test/include/test/jemalloc_test_defs.h.in" + +cfghdrs_out="include/jemalloc/jemalloc_defs.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_symbols.awk" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_symbols_jet.awk" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_symbols.txt" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_namespace.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_unnamespace.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_protos_jet.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_rename.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle_jet.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h" +cfghdrs_out="${cfghdrs_out} test/include/test/jemalloc_test_defs.h" + +cfghdrs_tup="include/jemalloc/jemalloc_defs.h:include/jemalloc/jemalloc_defs.h.in" +cfghdrs_tup="${cfghdrs_tup} include/jemalloc/internal/jemalloc_internal_defs.h:include/jemalloc/internal/jemalloc_internal_defs.h.in" +cfghdrs_tup="${cfghdrs_tup} test/include/test/jemalloc_test_defs.h:test/include/test/jemalloc_test_defs.h.in" + + +# Check whether --enable-debug was given. +if test ${enable_debug+y} +then : + enableval=$enable_debug; if test "x$enable_debug" = "xno" ; then + enable_debug="0" +else + enable_debug="1" +fi + +else $as_nop + enable_debug="0" + +fi + +if test "x$enable_debug" = "x1" ; then + printf "%s\n" "#define JEMALLOC_DEBUG " >>confdefs.h + +fi +if test "x$enable_debug" = "x1" ; then + printf "%s\n" "#define JEMALLOC_DEBUG " >>confdefs.h + +fi + + +if test "x$enable_debug" = "x0" ; then + if test "x$GCC" = "xyes" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -O3" >&5 +printf %s "checking whether compiler supports -O3... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-O3 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-O3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -O3" >&5 +printf %s "checking whether compiler supports -O3... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-O3 + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-O3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -funroll-loops" >&5 +printf %s "checking whether compiler supports -funroll-loops... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-funroll-loops + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-funroll-loops + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + elif test "x$je_cv_msvc" = "xyes" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -O2" >&5 +printf %s "checking whether compiler supports -O2... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-O2 + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-O2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -O2" >&5 +printf %s "checking whether compiler supports -O2... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-O2 + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-O2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + else + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -O" >&5 +printf %s "checking whether compiler supports -O... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-O + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-O + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -O" >&5 +printf %s "checking whether compiler supports -O... " >&6; } +T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}" +T_APPEND_V=-O + if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}${T_APPEND_V}" +else + CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO" +then : + je_cv_cxxflags_added=-O + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cxxflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x${CONFIGURE_CXXFLAGS}" = "x" -o "x${SPECIFIED_CXXFLAGS}" = "x" ; then + CXXFLAGS="${CONFIGURE_CXXFLAGS}${SPECIFIED_CXXFLAGS}" +else + CXXFLAGS="${CONFIGURE_CXXFLAGS} ${SPECIFIED_CXXFLAGS}" +fi + + + fi +fi + +# Check whether --enable-stats was given. +if test ${enable_stats+y} +then : + enableval=$enable_stats; if test "x$enable_stats" = "xno" ; then + enable_stats="0" +else + enable_stats="1" +fi + +else $as_nop + enable_stats="1" + +fi + +if test "x$enable_stats" = "x1" ; then + printf "%s\n" "#define JEMALLOC_STATS " >>confdefs.h + +fi + + +# Check whether --enable-experimental_smallocx was given. +if test ${enable_experimental_smallocx+y} +then : + enableval=$enable_experimental_smallocx; if test "x$enable_experimental_smallocx" = "xno" ; then +enable_experimental_smallocx="0" +else +enable_experimental_smallocx="1" +fi + +else $as_nop + enable_experimental_smallocx="0" + +fi + +if test "x$enable_experimental_smallocx" = "x1" ; then + printf "%s\n" "#define JEMALLOC_EXPERIMENTAL_SMALLOCX_API 1" >>confdefs.h + +fi + + +# Check whether --enable-prof was given. +if test ${enable_prof+y} +then : + enableval=$enable_prof; if test "x$enable_prof" = "xno" ; then + enable_prof="0" +else + enable_prof="1" +fi + +else $as_nop + enable_prof="0" + +fi + +if test "x$enable_prof" = "x1" ; then + backtrace_method="" +else + backtrace_method="N/A" +fi + +# Check whether --enable-prof-libunwind was given. +if test ${enable_prof_libunwind+y} +then : + enableval=$enable_prof_libunwind; if test "x$enable_prof_libunwind" = "xno" ; then + enable_prof_libunwind="0" +else + enable_prof_libunwind="1" +fi + +else $as_nop + enable_prof_libunwind="0" + +fi + + +# Check whether --with-static_libunwind was given. +if test ${with_static_libunwind+y} +then : + withval=$with_static_libunwind; if test "x$with_static_libunwind" = "xno" ; then + LUNWIND="-lunwind" +else + if test ! -f "$with_static_libunwind" ; then + as_fn_error $? "Static libunwind not found: $with_static_libunwind" "$LINENO" 5 + fi + LUNWIND="$with_static_libunwind" +fi +else $as_nop + LUNWIND="-lunwind" + +fi + +if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then + for ac_header in libunwind.h +do : + ac_fn_c_check_header_compile "$LINENO" "libunwind.h" "ac_cv_header_libunwind_h" "$ac_includes_default" +if test "x$ac_cv_header_libunwind_h" = xyes +then : + printf "%s\n" "#define HAVE_LIBUNWIND_H 1" >>confdefs.h + +else $as_nop + enable_prof_libunwind="0" +fi + +done + if test "x$LUNWIND" = "x-lunwind" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unw_backtrace in -lunwind" >&5 +printf %s "checking for unw_backtrace in -lunwind... " >&6; } +if test ${ac_cv_lib_unwind_unw_backtrace+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lunwind $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char unw_backtrace (); +int +main (void) +{ +return unw_backtrace (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_unwind_unw_backtrace=yes +else $as_nop + ac_cv_lib_unwind_unw_backtrace=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unwind_unw_backtrace" >&5 +printf "%s\n" "$ac_cv_lib_unwind_unw_backtrace" >&6; } +if test "x$ac_cv_lib_unwind_unw_backtrace" = xyes +then : + T_APPEND_V=$LUNWIND + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + +else $as_nop + enable_prof_libunwind="0" +fi + + else + T_APPEND_V=$LUNWIND + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + + fi + if test "x${enable_prof_libunwind}" = "x1" ; then + backtrace_method="libunwind" + printf "%s\n" "#define JEMALLOC_PROF_LIBUNWIND " >>confdefs.h + + fi +fi + +# Check whether --enable-prof-libgcc was given. +if test ${enable_prof_libgcc+y} +then : + enableval=$enable_prof_libgcc; if test "x$enable_prof_libgcc" = "xno" ; then + enable_prof_libgcc="0" +else + enable_prof_libgcc="1" +fi + +else $as_nop + enable_prof_libgcc="1" + +fi + +if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \ + -a "x$GCC" = "xyes" ; then + for ac_header in unwind.h +do : + ac_fn_c_check_header_compile "$LINENO" "unwind.h" "ac_cv_header_unwind_h" "$ac_includes_default" +if test "x$ac_cv_header_unwind_h" = xyes +then : + printf "%s\n" "#define HAVE_UNWIND_H 1" >>confdefs.h + +else $as_nop + enable_prof_libgcc="0" +fi + +done + if test "x${enable_prof_libgcc}" = "x1" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _Unwind_Backtrace in -lgcc" >&5 +printf %s "checking for _Unwind_Backtrace in -lgcc... " >&6; } +if test ${ac_cv_lib_gcc__Unwind_Backtrace+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgcc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char _Unwind_Backtrace (); +int +main (void) +{ +return _Unwind_Backtrace (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_gcc__Unwind_Backtrace=yes +else $as_nop + ac_cv_lib_gcc__Unwind_Backtrace=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gcc__Unwind_Backtrace" >&5 +printf "%s\n" "$ac_cv_lib_gcc__Unwind_Backtrace" >&6; } +if test "x$ac_cv_lib_gcc__Unwind_Backtrace" = xyes +then : + T_APPEND_V=-lgcc + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + +else $as_nop + enable_prof_libgcc="0" +fi + + fi + if test "x${enable_prof_libgcc}" = "x1" ; then + backtrace_method="libgcc" + printf "%s\n" "#define JEMALLOC_PROF_LIBGCC " >>confdefs.h + + fi +else + enable_prof_libgcc="0" +fi + +# Check whether --enable-prof-gcc was given. +if test ${enable_prof_gcc+y} +then : + enableval=$enable_prof_gcc; if test "x$enable_prof_gcc" = "xno" ; then + enable_prof_gcc="0" +else + enable_prof_gcc="1" +fi + +else $as_nop + enable_prof_gcc="1" + +fi + +if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \ + -a "x$GCC" = "xyes" ; then + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -fno-omit-frame-pointer" >&5 +printf %s "checking whether compiler supports -fno-omit-frame-pointer... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-fno-omit-frame-pointer + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-fno-omit-frame-pointer + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + backtrace_method="gcc intrinsics" + printf "%s\n" "#define JEMALLOC_PROF_GCC " >>confdefs.h + +else + enable_prof_gcc="0" +fi + +if test "x$backtrace_method" = "x" ; then + backtrace_method="none (disabling profiling)" + enable_prof="0" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking configured backtracing method" >&5 +printf %s "checking configured backtracing method... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $backtrace_method" >&5 +printf "%s\n" "$backtrace_method" >&6; } +if test "x$enable_prof" = "x1" ; then + T_APPEND_V=$LM + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + + + printf "%s\n" "#define JEMALLOC_PROF " >>confdefs.h + +fi + + +if test "x${maps_coalesce}" = "x1" ; then + printf "%s\n" "#define JEMALLOC_MAPS_COALESCE " >>confdefs.h + +fi + +if test "x$default_retain" = "x1" ; then + printf "%s\n" "#define JEMALLOC_RETAIN " >>confdefs.h + +fi + +have_dss="1" +ac_fn_c_check_func "$LINENO" "sbrk" "ac_cv_func_sbrk" +if test "x$ac_cv_func_sbrk" = xyes +then : + have_sbrk="1" +else $as_nop + have_sbrk="0" +fi + +if test "x$have_sbrk" = "x1" ; then + if test "x$sbrk_deprecated" = "x1" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Disabling dss allocation because sbrk is deprecated" >&5 +printf "%s\n" "Disabling dss allocation because sbrk is deprecated" >&6; } + have_dss="0" + fi +else + have_dss="0" +fi + +if test "x$have_dss" = "x1" ; then + printf "%s\n" "#define JEMALLOC_DSS " >>confdefs.h + +fi + +# Check whether --enable-fill was given. +if test ${enable_fill+y} +then : + enableval=$enable_fill; if test "x$enable_fill" = "xno" ; then + enable_fill="0" +else + enable_fill="1" +fi + +else $as_nop + enable_fill="1" + +fi + +if test "x$enable_fill" = "x1" ; then + printf "%s\n" "#define JEMALLOC_FILL " >>confdefs.h + +fi + + +# Check whether --enable-utrace was given. +if test ${enable_utrace+y} +then : + enableval=$enable_utrace; if test "x$enable_utrace" = "xno" ; then + enable_utrace="0" +else + enable_utrace="1" +fi + +else $as_nop + enable_utrace="0" + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether utrace(2) is compilable" >&5 +printf %s "checking whether utrace(2) is compilable... " >&6; } +if test ${je_cv_utrace+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int +main (void) +{ + + utrace((void *)0, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_utrace=yes +else $as_nop + je_cv_utrace=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_utrace" >&5 +printf "%s\n" "$je_cv_utrace" >&6; } + +if test "x${je_cv_utrace}" = "xno" ; then + enable_utrace="0" +fi +if test "x$enable_utrace" = "x1" ; then + printf "%s\n" "#define JEMALLOC_UTRACE " >>confdefs.h + +fi + + +# Check whether --enable-xmalloc was given. +if test ${enable_xmalloc+y} +then : + enableval=$enable_xmalloc; if test "x$enable_xmalloc" = "xno" ; then + enable_xmalloc="0" +else + enable_xmalloc="1" +fi + +else $as_nop + enable_xmalloc="0" + +fi + +if test "x$enable_xmalloc" = "x1" ; then + printf "%s\n" "#define JEMALLOC_XMALLOC " >>confdefs.h + +fi + + +# Check whether --enable-cache-oblivious was given. +if test ${enable_cache_oblivious+y} +then : + enableval=$enable_cache_oblivious; if test "x$enable_cache_oblivious" = "xno" ; then + enable_cache_oblivious="0" +else + enable_cache_oblivious="1" +fi + +else $as_nop + enable_cache_oblivious="1" + +fi + +if test "x$enable_cache_oblivious" = "x1" ; then + printf "%s\n" "#define JEMALLOC_CACHE_OBLIVIOUS " >>confdefs.h + +fi + + +# Check whether --enable-log was given. +if test ${enable_log+y} +then : + enableval=$enable_log; if test "x$enable_log" = "xno" ; then + enable_log="0" +else + enable_log="1" +fi + +else $as_nop + enable_log="0" + +fi + +if test "x$enable_log" = "x1" ; then + printf "%s\n" "#define JEMALLOC_LOG " >>confdefs.h + +fi + + +# Check whether --enable-readlinkat was given. +if test ${enable_readlinkat+y} +then : + enableval=$enable_readlinkat; if test "x$enable_readlinkat" = "xno" ; then + enable_readlinkat="0" +else + enable_readlinkat="1" +fi + +else $as_nop + enable_readlinkat="0" + +fi + +if test "x$enable_readlinkat" = "x1" ; then + printf "%s\n" "#define JEMALLOC_READLINKAT " >>confdefs.h + +fi + + +# Check whether --enable-opt-safety-checks was given. +if test ${enable_opt_safety_checks+y} +then : + enableval=$enable_opt_safety_checks; if test "x$enable_opt_safety_checks" = "xno" ; then + enable_opt_safety_checks="0" +else + enable_opt_safety_checks="1" +fi + +else $as_nop + enable_opt_safety_checks="0" + +fi + +if test "x$enable_opt_safety_checks" = "x1" ; then + printf "%s\n" "#define JEMALLOC_OPT_SAFETY_CHECKS " >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program using __builtin_unreachable is compilable" >&5 +printf %s "checking whether a program using __builtin_unreachable is compilable... " >&6; } +if test ${je_cv_gcc_builtin_unreachable+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +void foo (void) { + __builtin_unreachable(); +} + +int +main (void) +{ + + { + foo(); + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_builtin_unreachable=yes +else $as_nop + je_cv_gcc_builtin_unreachable=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_builtin_unreachable" >&5 +printf "%s\n" "$je_cv_gcc_builtin_unreachable" >&6; } + +if test "x${je_cv_gcc_builtin_unreachable}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_INTERNAL_UNREACHABLE __builtin_unreachable" >>confdefs.h + +else + printf "%s\n" "#define JEMALLOC_INTERNAL_UNREACHABLE abort" >>confdefs.h + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program using __builtin_ffsl is compilable" >&5 +printf %s "checking whether a program using __builtin_ffsl is compilable... " >&6; } +if test ${je_cv_gcc_builtin_ffsl+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include + +int +main (void) +{ + + { + int rv = __builtin_ffsl(0x08); + printf("%d\n", rv); + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_builtin_ffsl=yes +else $as_nop + je_cv_gcc_builtin_ffsl=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_builtin_ffsl" >&5 +printf "%s\n" "$je_cv_gcc_builtin_ffsl" >&6; } + +if test "x${je_cv_gcc_builtin_ffsl}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_INTERNAL_FFSLL __builtin_ffsll" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_INTERNAL_FFSL __builtin_ffsl" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_INTERNAL_FFS __builtin_ffs" >>confdefs.h + +else + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program using ffsl is compilable" >&5 +printf %s "checking whether a program using ffsl is compilable... " >&6; } +if test ${je_cv_function_ffsl+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + +int +main (void) +{ + + { + int rv = ffsl(0x08); + printf("%d\n", rv); + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_function_ffsl=yes +else $as_nop + je_cv_function_ffsl=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_function_ffsl" >&5 +printf "%s\n" "$je_cv_function_ffsl" >&6; } + + if test "x${je_cv_function_ffsl}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_INTERNAL_FFSLL ffsll" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_INTERNAL_FFSL ffsl" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_INTERNAL_FFS ffs" >>confdefs.h + + else + as_fn_error $? "Cannot build without ffsl(3) or __builtin_ffsl()" "$LINENO" 5 + fi +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program using __builtin_popcountl is compilable" >&5 +printf %s "checking whether a program using __builtin_popcountl is compilable... " >&6; } +if test ${je_cv_gcc_builtin_popcountl+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include + +int +main (void) +{ + + { + int rv = __builtin_popcountl(0x08); + printf("%d\n", rv); + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_builtin_popcountl=yes +else $as_nop + je_cv_gcc_builtin_popcountl=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_builtin_popcountl" >&5 +printf "%s\n" "$je_cv_gcc_builtin_popcountl" >&6; } + +if test "x${je_cv_gcc_builtin_popcountl}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_INTERNAL_POPCOUNT __builtin_popcount" >>confdefs.h + + printf "%s\n" "#define JEMALLOC_INTERNAL_POPCOUNTL __builtin_popcountl" >>confdefs.h + +fi + + +# Check whether --with-lg_quantum was given. +if test ${with_lg_quantum+y} +then : + withval=$with_lg_quantum; LG_QUANTA="$with_lg_quantum" +else $as_nop + LG_QUANTA="3 4" +fi + +if test "x$with_lg_quantum" != "x" ; then + printf "%s\n" "#define LG_QUANTUM $with_lg_quantum" >>confdefs.h + +fi + + +# Check whether --with-lg_page was given. +if test ${with_lg_page+y} +then : + withval=$with_lg_page; LG_PAGE="$with_lg_page" +else $as_nop + LG_PAGE="detect" +fi + +if test "x$LG_PAGE" = "xdetect"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LG_PAGE" >&5 +printf %s "checking LG_PAGE... " >&6; } +if test ${je_cv_lg_page+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + je_cv_lg_page=12 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef _WIN32 +#include +#else +#include +#endif +#include + +int +main (void) +{ + + int result; + FILE *f; + +#ifdef _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + result = si.dwPageSize; +#else + result = sysconf(_SC_PAGESIZE); +#endif + if (result == -1) { + return 1; + } + result = JEMALLOC_INTERNAL_FFSL(result) - 1; + + f = fopen("conftest.out", "w"); + if (f == NULL) { + return 1; + } + fprintf(f, "%d", result); + fclose(f); + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + je_cv_lg_page=`cat conftest.out` +else $as_nop + je_cv_lg_page=undefined +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_lg_page" >&5 +printf "%s\n" "$je_cv_lg_page" >&6; } +fi +if test "x${je_cv_lg_page}" != "x" ; then + LG_PAGE="${je_cv_lg_page}" +fi +if test "x${LG_PAGE}" != "xundefined" ; then + printf "%s\n" "#define LG_PAGE $LG_PAGE" >>confdefs.h + +else + as_fn_error $? "cannot determine value for LG_PAGE" "$LINENO" 5 +fi + + +# Check whether --with-lg_hugepage was given. +if test ${with_lg_hugepage+y} +then : + withval=$with_lg_hugepage; je_cv_lg_hugepage="${with_lg_hugepage}" +else $as_nop + je_cv_lg_hugepage="" +fi + +if test "x${je_cv_lg_hugepage}" = "x" ; then + if test -e "/proc/meminfo" ; then + hpsk=`cat /proc/meminfo 2>/dev/null | \ + grep -e '^Hugepagesize:[[:space:]]\+[0-9]\+[[:space:]]kB$' | \ + awk '{print $2}'` + if test "x${hpsk}" != "x" ; then + je_cv_lg_hugepage=10 + while test "${hpsk}" -gt 1 ; do + hpsk="$((hpsk / 2))" + je_cv_lg_hugepage="$((je_cv_lg_hugepage + 1))" + done + fi + fi + + if test "x${je_cv_lg_hugepage}" = "x" ; then + je_cv_lg_hugepage=21 + fi +fi +if test "x${LG_PAGE}" != "xundefined" -a \ + "${je_cv_lg_hugepage}" -lt "${LG_PAGE}" ; then + as_fn_error $? "Huge page size (2^${je_cv_lg_hugepage}) must be at least page size (2^${LG_PAGE})" "$LINENO" 5 +fi +printf "%s\n" "#define LG_HUGEPAGE ${je_cv_lg_hugepage}" >>confdefs.h + + +# Check whether --enable-libdl was given. +if test ${enable_libdl+y} +then : + enableval=$enable_libdl; if test "x$enable_libdl" = "xno" ; then + enable_libdl="0" +else + enable_libdl="1" +fi + +else $as_nop + enable_libdl="1" + +fi + + + + +if test "x$abi" != "xpecoff" ; then + printf "%s\n" "#define JEMALLOC_HAVE_PTHREAD " >>confdefs.h + + for ac_header in pthread.h +do : + ac_fn_c_check_header_compile "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_H 1" >>confdefs.h + +else $as_nop + as_fn_error $? "pthread.h is missing" "$LINENO" 5 +fi + +done + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +printf %s "checking for pthread_create in -lpthread... " >&6; } +if test ${ac_cv_lib_pthread_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main (void) +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_pthread_pthread_create=yes +else $as_nop + ac_cv_lib_pthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes +then : + T_APPEND_V=-pthread + if test "x${LIBS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + LIBS="${LIBS}${T_APPEND_V}" +else + LIBS="${LIBS} ${T_APPEND_V}" +fi + + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 +printf %s "checking for library containing pthread_create... " >&6; } +if test ${ac_cv_search_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char pthread_create (); +int +main (void) +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_pthread_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_pthread_create+y} +then : + break +fi +done +if test ${ac_cv_search_pthread_create+y} +then : + +else $as_nop + ac_cv_search_pthread_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +printf "%s\n" "$ac_cv_search_pthread_create" >&6; } +ac_res=$ac_cv_search_pthread_create +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else $as_nop + as_fn_error $? "libpthread is missing" "$LINENO" 5 +fi + +fi + + wrap_syms="${wrap_syms} pthread_create" + have_pthread="1" + + if test "x$enable_libdl" = "x1" ; then + have_dlsym="1" + for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h + ac_fn_c_check_func "$LINENO" "dlsym" "ac_cv_func_dlsym" +if test "x$ac_cv_func_dlsym" = xyes +then : + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5 +printf %s "checking for dlsym in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlsym+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char dlsym (); +int +main (void) +{ +return dlsym (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_dl_dlsym=yes +else $as_nop + ac_cv_lib_dl_dlsym=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlsym" >&6; } +if test "x$ac_cv_lib_dl_dlsym" = xyes +then : + LIBS="$LIBS -ldl" +else $as_nop + have_dlsym="0" +fi + +fi + +else $as_nop + have_dlsym="0" +fi + +done + if test "x$have_dlsym" = "x1" ; then + printf "%s\n" "#define JEMALLOC_HAVE_DLSYM " >>confdefs.h + + fi + else + have_dlsym="0" + fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_atfork(3) is compilable" >&5 +printf %s "checking whether pthread_atfork(3) is compilable... " >&6; } +if test ${je_cv_pthread_atfork+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + pthread_atfork((void *)0, (void *)0, (void *)0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_pthread_atfork=yes +else $as_nop + je_cv_pthread_atfork=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_pthread_atfork" >&5 +printf "%s\n" "$je_cv_pthread_atfork" >&6; } + + if test "x${je_cv_pthread_atfork}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_PTHREAD_ATFORK " >>confdefs.h + + fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np(3) is compilable" >&5 +printf %s "checking whether pthread_setname_np(3) is compilable... " >&6; } +if test ${je_cv_pthread_setname_np+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + pthread_setname_np(pthread_self(), "setname_test"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_pthread_setname_np=yes +else $as_nop + je_cv_pthread_setname_np=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_pthread_setname_np" >&5 +printf "%s\n" "$je_cv_pthread_setname_np" >&6; } + + if test "x${je_cv_pthread_setname_np}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_PTHREAD_SETNAME_NP " >>confdefs.h + + fi +fi + +T_APPEND_V=-D_REENTRANT + if test "x${CPPFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CPPFLAGS="${CPPFLAGS}${T_APPEND_V}" +else + CPPFLAGS="${CPPFLAGS} ${T_APPEND_V}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +printf %s "checking for library containing clock_gettime... " >&6; } +if test ${ac_cv_search_clock_gettime+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_gettime (); +int +main (void) +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_clock_gettime+y} +then : + break +fi +done +if test ${ac_cv_search_clock_gettime+y} +then : + +else $as_nop + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +printf "%s\n" "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then + if test "$ac_cv_search_clock_gettime" != "-lrt"; then + SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + + unset ac_cv_search_clock_gettime + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -dynamic" >&5 +printf %s "checking whether compiler supports -dynamic... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-dynamic + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-dynamic + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +printf %s "checking for library containing clock_gettime... " >&6; } +if test ${ac_cv_search_clock_gettime+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_gettime (); +int +main (void) +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_clock_gettime+y} +then : + break +fi +done +if test ${ac_cv_search_clock_gettime+y} +then : + +else $as_nop + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +printf "%s\n" "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + + CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + fi +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is compilable" >&5 +printf %s "checking whether clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is compilable... " >&6; } +if test ${je_cv_clock_monotonic_coarse+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_clock_monotonic_coarse=yes +else $as_nop + je_cv_clock_monotonic_coarse=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_clock_monotonic_coarse" >&5 +printf "%s\n" "$je_cv_clock_monotonic_coarse" >&6; } + +if test "x${je_cv_clock_monotonic_coarse}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE 1" >>confdefs.h + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether clock_gettime(CLOCK_MONOTONIC, ...) is compilable" >&5 +printf %s "checking whether clock_gettime(CLOCK_MONOTONIC, ...) is compilable... " >&6; } +if test ${je_cv_clock_monotonic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main (void) +{ + + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); +#if !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0 +# error _POSIX_MONOTONIC_CLOCK missing/invalid +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_clock_monotonic=yes +else $as_nop + je_cv_clock_monotonic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_clock_monotonic" >&5 +printf "%s\n" "$je_cv_clock_monotonic" >&6; } + +if test "x${je_cv_clock_monotonic}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_CLOCK_MONOTONIC 1" >>confdefs.h + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether mach_absolute_time() is compilable" >&5 +printf %s "checking whether mach_absolute_time() is compilable... " >&6; } +if test ${je_cv_mach_absolute_time+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + mach_absolute_time(); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_mach_absolute_time=yes +else $as_nop + je_cv_mach_absolute_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_mach_absolute_time" >&5 +printf "%s\n" "$je_cv_mach_absolute_time" >&6; } + +if test "x${je_cv_mach_absolute_time}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_MACH_ABSOLUTE_TIME 1" >>confdefs.h + +fi + +# Check whether --enable-syscall was given. +if test ${enable_syscall+y} +then : + enableval=$enable_syscall; if test "x$enable_syscall" = "xno" ; then + enable_syscall="0" +else + enable_syscall="1" +fi + +else $as_nop + enable_syscall="1" + +fi + +if test "x$enable_syscall" = "x1" ; then + SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether syscall(2) is compilable" >&5 +printf %s "checking whether syscall(2) is compilable... " >&6; } +if test ${je_cv_syscall+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main (void) +{ + + syscall(SYS_write, 2, "hello", 5); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_syscall=yes +else $as_nop + je_cv_syscall=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_syscall" >&5 +printf "%s\n" "$je_cv_syscall" >&6; } + + CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + if test "x$je_cv_syscall" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_USE_SYSCALL " >>confdefs.h + + fi +fi + +ac_fn_c_check_func "$LINENO" "secure_getenv" "ac_cv_func_secure_getenv" +if test "x$ac_cv_func_secure_getenv" = xyes +then : + have_secure_getenv="1" +else $as_nop + have_secure_getenv="0" + +fi + +if test "x$have_secure_getenv" = "x1" ; then + printf "%s\n" "#define JEMALLOC_HAVE_SECURE_GETENV " >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "sched_getcpu" "ac_cv_func_sched_getcpu" +if test "x$ac_cv_func_sched_getcpu" = xyes +then : + have_sched_getcpu="1" +else $as_nop + have_sched_getcpu="0" + +fi + +if test "x$have_sched_getcpu" = "x1" ; then + printf "%s\n" "#define JEMALLOC_HAVE_SCHED_GETCPU " >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "sched_setaffinity" "ac_cv_func_sched_setaffinity" +if test "x$ac_cv_func_sched_setaffinity" = xyes +then : + have_sched_setaffinity="1" +else $as_nop + have_sched_setaffinity="0" + +fi + +if test "x$have_sched_setaffinity" = "x1" ; then + printf "%s\n" "#define JEMALLOC_HAVE_SCHED_SETAFFINITY " >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "issetugid" "ac_cv_func_issetugid" +if test "x$ac_cv_func_issetugid" = xyes +then : + have_issetugid="1" +else $as_nop + have_issetugid="0" + +fi + +if test "x$have_issetugid" = "x1" ; then + printf "%s\n" "#define JEMALLOC_HAVE_ISSETUGID " >>confdefs.h + +fi + +ac_fn_c_check_func "$LINENO" "_malloc_thread_cleanup" "ac_cv_func__malloc_thread_cleanup" +if test "x$ac_cv_func__malloc_thread_cleanup" = xyes +then : + have__malloc_thread_cleanup="1" +else $as_nop + have__malloc_thread_cleanup="0" + +fi + +if test "x$have__malloc_thread_cleanup" = "x1" ; then + printf "%s\n" "#define JEMALLOC_MALLOC_THREAD_CLEANUP " >>confdefs.h + + wrap_syms="${wrap_syms} _malloc_thread_cleanup" + force_tls="1" +fi + +ac_fn_c_check_func "$LINENO" "_pthread_mutex_init_calloc_cb" "ac_cv_func__pthread_mutex_init_calloc_cb" +if test "x$ac_cv_func__pthread_mutex_init_calloc_cb" = xyes +then : + have__pthread_mutex_init_calloc_cb="1" +else $as_nop + have__pthread_mutex_init_calloc_cb="0" + +fi + +if test "x$have__pthread_mutex_init_calloc_cb" = "x1" ; then + printf "%s\n" "#define JEMALLOC_MUTEX_INIT_CB 1" >>confdefs.h + + wrap_syms="${wrap_syms} _malloc_prefork _malloc_postfork" +fi + +# Check whether --enable-lazy_lock was given. +if test ${enable_lazy_lock+y} +then : + enableval=$enable_lazy_lock; if test "x$enable_lazy_lock" = "xno" ; then + enable_lazy_lock="0" +else + enable_lazy_lock="1" +fi + +else $as_nop + enable_lazy_lock="" + +fi + +if test "x${enable_lazy_lock}" = "x" ; then + if test "x${force_lazy_lock}" = "x1" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Forcing lazy-lock to avoid allocator/threading bootstrap issues" >&5 +printf "%s\n" "Forcing lazy-lock to avoid allocator/threading bootstrap issues" >&6; } + enable_lazy_lock="1" + else + enable_lazy_lock="0" + fi +fi +if test "x${enable_lazy_lock}" = "x1" -a "x${abi}" = "xpecoff" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Forcing no lazy-lock because thread creation monitoring is unimplemented" >&5 +printf "%s\n" "Forcing no lazy-lock because thread creation monitoring is unimplemented" >&6; } + enable_lazy_lock="0" +fi +if test "x$enable_lazy_lock" = "x1" ; then + if test "x$have_dlsym" = "x1" ; then + printf "%s\n" "#define JEMALLOC_LAZY_LOCK " >>confdefs.h + + else + as_fn_error $? "Missing dlsym support: lazy-lock cannot be enabled." "$LINENO" 5 + fi +fi + + +if test "x${force_tls}" = "x1" ; then + enable_tls="1" +elif test "x${force_tls}" = "x0" ; then + enable_tls="0" +else + enable_tls="1" +fi +if test "x${enable_tls}" = "x1" ; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for TLS" >&5 +printf %s "checking for TLS... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + __thread int x; + +int +main (void) +{ + + x = 42; + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + enable_tls="0" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +else + enable_tls="0" +fi + +if test "x${enable_tls}" = "x1" ; then + printf "%s\n" "#define JEMALLOC_TLS " >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C11 atomics is compilable" >&5 +printf %s "checking whether C11 atomics is compilable... " >&6; } +if test ${je_cv_c11_atomics+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#if (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__) +#include +#else +#error Atomics not available +#endif + +int +main (void) +{ + + uint64_t *p = (uint64_t *)0; + uint64_t x = 1; + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + uint64_t r = atomic_fetch_add(a, x) + x; + return r == 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_c11_atomics=yes +else $as_nop + je_cv_c11_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_c11_atomics" >&5 +printf "%s\n" "$je_cv_c11_atomics" >&6; } + +if test "x${je_cv_c11_atomics}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_C11_ATOMICS 1" >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GCC __atomic atomics is compilable" >&5 +printf %s "checking whether GCC __atomic atomics is compilable... " >&6; } +if test ${je_cv_gcc_atomic_atomics+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + int x = 0; + int val = 1; + int y = __atomic_fetch_add(&x, val, __ATOMIC_RELAXED); + int after_add = x; + return after_add == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_atomic_atomics=yes +else $as_nop + je_cv_gcc_atomic_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_atomic_atomics" >&5 +printf "%s\n" "$je_cv_gcc_atomic_atomics" >&6; } + +if test "x${je_cv_gcc_atomic_atomics}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_GCC_ATOMIC_ATOMICS 1" >>confdefs.h + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GCC 8-bit __atomic atomics is compilable" >&5 +printf %s "checking whether GCC 8-bit __atomic atomics is compilable... " >&6; } +if test ${je_cv_gcc_u8_atomic_atomics+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + unsigned char x = 0; + int val = 1; + int y = __atomic_fetch_add(&x, val, __ATOMIC_RELAXED); + int after_add = (int)x; + return after_add == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_u8_atomic_atomics=yes +else $as_nop + je_cv_gcc_u8_atomic_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_u8_atomic_atomics" >&5 +printf "%s\n" "$je_cv_gcc_u8_atomic_atomics" >&6; } + + if test "x${je_cv_gcc_u8_atomic_atomics}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_GCC_U8_ATOMIC_ATOMICS 1" >>confdefs.h + + fi +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GCC __sync atomics is compilable" >&5 +printf %s "checking whether GCC __sync atomics is compilable... " >&6; } +if test ${je_cv_gcc_sync_atomics+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + int x = 0; + int before_add = __sync_fetch_and_add(&x, 1); + int after_add = x; + return (before_add == 0) && (after_add == 1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_sync_atomics=yes +else $as_nop + je_cv_gcc_sync_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_sync_atomics" >&5 +printf "%s\n" "$je_cv_gcc_sync_atomics" >&6; } + +if test "x${je_cv_gcc_sync_atomics}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_GCC_SYNC_ATOMICS 1" >>confdefs.h + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether GCC 8-bit __sync atomics is compilable" >&5 +printf %s "checking whether GCC 8-bit __sync atomics is compilable... " >&6; } +if test ${je_cv_gcc_u8_sync_atomics+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + unsigned char x = 0; + int before_add = __sync_fetch_and_add(&x, 1); + int after_add = (int)x; + return (before_add == 0) && (after_add == 1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_gcc_u8_sync_atomics=yes +else $as_nop + je_cv_gcc_u8_sync_atomics=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_gcc_u8_sync_atomics" >&5 +printf "%s\n" "$je_cv_gcc_u8_sync_atomics" >&6; } + + if test "x${je_cv_gcc_u8_sync_atomics}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_GCC_U8_SYNC_ATOMICS 1" >>confdefs.h + + fi +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Darwin OSAtomic*() is compilable" >&5 +printf %s "checking whether Darwin OSAtomic*() is compilable... " >&6; } +if test ${je_cv_osatomic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main (void) +{ + + { + int32_t x32 = 0; + volatile int32_t *x32p = &x32; + OSAtomicAdd32(1, x32p); + } + { + int64_t x64 = 0; + volatile int64_t *x64p = &x64; + OSAtomicAdd64(1, x64p); + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_osatomic=yes +else $as_nop + je_cv_osatomic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_osatomic" >&5 +printf "%s\n" "$je_cv_osatomic" >&6; } + +if test "x${je_cv_osatomic}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_OSATOMIC " >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether madvise(2) is compilable" >&5 +printf %s "checking whether madvise(2) is compilable... " >&6; } +if test ${je_cv_madvise+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + madvise((void *)0, 0, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_madvise=yes +else $as_nop + je_cv_madvise=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_madvise" >&5 +printf "%s\n" "$je_cv_madvise" >&6; } + +if test "x${je_cv_madvise}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_MADVISE " >>confdefs.h + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_FREE) is compilable" >&5 +printf %s "checking whether madvise(..., MADV_FREE) is compilable... " >&6; } +if test ${je_cv_madv_free+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + madvise((void *)0, 0, MADV_FREE); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_madv_free=yes +else $as_nop + je_cv_madv_free=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_madv_free" >&5 +printf "%s\n" "$je_cv_madv_free" >&6; } + + if test "x${je_cv_madv_free}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h + + elif test "x${je_cv_madvise}" = "xyes" ; then + case "${host_cpu}" in i686|x86_64) + case "${host}" in *-*-linux*) + printf "%s\n" "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h + + printf "%s\n" "#define JEMALLOC_DEFINE_MADVISE_FREE " >>confdefs.h + + ;; + esac + ;; + esac + fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_DONTNEED) is compilable" >&5 +printf %s "checking whether madvise(..., MADV_DONTNEED) is compilable... " >&6; } +if test ${je_cv_madv_dontneed+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + madvise((void *)0, 0, MADV_DONTNEED); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_madv_dontneed=yes +else $as_nop + je_cv_madv_dontneed=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_madv_dontneed" >&5 +printf "%s\n" "$je_cv_madv_dontneed" >&6; } + + if test "x${je_cv_madv_dontneed}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_PURGE_MADVISE_DONTNEED " >>confdefs.h + + fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_DO[NT]DUMP) is compilable" >&5 +printf %s "checking whether madvise(..., MADV_DO[NT]DUMP) is compilable... " >&6; } +if test ${je_cv_madv_dontdump+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + madvise((void *)0, 0, MADV_DONTDUMP); + madvise((void *)0, 0, MADV_DODUMP); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_madv_dontdump=yes +else $as_nop + je_cv_madv_dontdump=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_madv_dontdump" >&5 +printf "%s\n" "$je_cv_madv_dontdump" >&6; } + + if test "x${je_cv_madv_dontdump}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_MADVISE_DONTDUMP " >>confdefs.h + + fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_[NO]HUGEPAGE) is compilable" >&5 +printf %s "checking whether madvise(..., MADV_[NO]HUGEPAGE) is compilable... " >&6; } +if test ${je_cv_thp+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + madvise((void *)0, 0, MADV_HUGEPAGE); + madvise((void *)0, 0, MADV_NOHUGEPAGE); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_thp=yes +else $as_nop + je_cv_thp=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_thp" >&5 +printf "%s\n" "$je_cv_thp" >&6; } + +case "${host_cpu}" in + arm*) + ;; + *) + if test "x${je_cv_thp}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_MADVISE_HUGE " >>confdefs.h + + fi + ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __builtin_clz" >&5 +printf %s "checking for __builtin_clz... " >&6; } +if test ${je_cv_builtin_clz+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + { + unsigned x = 0; + int y = __builtin_clz(x); + } + { + unsigned long x = 0; + int y = __builtin_clzl(x); + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_builtin_clz=yes +else $as_nop + je_cv_builtin_clz=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_builtin_clz" >&5 +printf "%s\n" "$je_cv_builtin_clz" >&6; } + +if test "x${je_cv_builtin_clz}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_BUILTIN_CLZ " >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Darwin os_unfair_lock_*() is compilable" >&5 +printf %s "checking whether Darwin os_unfair_lock_*() is compilable... " >&6; } +if test ${je_cv_os_unfair_lock+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main (void) +{ + + #if MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + #error "os_unfair_lock is not supported" + #else + os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; + os_unfair_lock_lock(&lock); + os_unfair_lock_unlock(&lock); + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_os_unfair_lock=yes +else $as_nop + je_cv_os_unfair_lock=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_os_unfair_lock" >&5 +printf "%s\n" "$je_cv_os_unfair_lock" >&6; } + +if test "x${je_cv_os_unfair_lock}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_OS_UNFAIR_LOCK " >>confdefs.h + +fi + + +# Check whether --enable-zone-allocator was given. +if test ${enable_zone_allocator+y} +then : + enableval=$enable_zone_allocator; if test "x$enable_zone_allocator" = "xno" ; then + enable_zone_allocator="0" +else + enable_zone_allocator="1" +fi + +else $as_nop + if test "x${abi}" = "xmacho"; then + enable_zone_allocator="1" +fi + + +fi + + + +if test "x${enable_zone_allocator}" = "x1" ; then + if test "x${abi}" != "xmacho"; then + as_fn_error $? "--enable-zone-allocator is only supported on Darwin" "$LINENO" 5 + fi + printf "%s\n" "#define JEMALLOC_ZONE " >>confdefs.h + +fi + +# Check whether --enable-initial-exec-tls was given. +if test ${enable_initial_exec_tls+y} +then : + enableval=$enable_initial_exec_tls; if test "x$enable_initial_exec_tls" = "xno" ; then + enable_initial_exec_tls="0" +else + enable_initial_exec_tls="1" +fi + +else $as_nop + enable_initial_exec_tls="1" + +fi + + + +if test "x${je_cv_tls_model}" = "xyes" -a \ + "x${enable_initial_exec_tls}" = "x1" ; then + printf "%s\n" "#define JEMALLOC_TLS_MODEL __attribute__((tls_model(\"initial-exec\")))" >>confdefs.h + +else + printf "%s\n" "#define JEMALLOC_TLS_MODEL " >>confdefs.h + +fi + + +if test "x${have_pthread}" = "x1" -a "x${je_cv_os_unfair_lock}" != "xyes" ; then + printf "%s\n" "#define JEMALLOC_BACKGROUND_THREAD 1" >>confdefs.h + +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether glibc malloc hook is compilable" >&5 +printf %s "checking whether glibc malloc hook is compilable... " >&6; } +if test ${je_cv_glibc_malloc_hook+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +extern void (* __free_hook)(void *ptr); +extern void *(* __malloc_hook)(size_t size); +extern void *(* __realloc_hook)(void *ptr, size_t size); + +int +main (void) +{ + + void *ptr = 0L; + if (__malloc_hook) ptr = __malloc_hook(1); + if (__realloc_hook) ptr = __realloc_hook(ptr, 2); + if (__free_hook && ptr) __free_hook(ptr); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_glibc_malloc_hook=yes +else $as_nop + je_cv_glibc_malloc_hook=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_glibc_malloc_hook" >&5 +printf "%s\n" "$je_cv_glibc_malloc_hook" >&6; } + +if test "x${je_cv_glibc_malloc_hook}" = "xyes" ; then + if test "x${JEMALLOC_PREFIX}" = "x" ; then + printf "%s\n" "#define JEMALLOC_GLIBC_MALLOC_HOOK " >>confdefs.h + + wrap_syms="${wrap_syms} __free_hook __malloc_hook __realloc_hook" + fi +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether glibc memalign hook is compilable" >&5 +printf %s "checking whether glibc memalign hook is compilable... " >&6; } +if test ${je_cv_glibc_memalign_hook+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +extern void *(* __memalign_hook)(size_t alignment, size_t size); + +int +main (void) +{ + + void *ptr = 0L; + if (__memalign_hook) ptr = __memalign_hook(16, 7); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_glibc_memalign_hook=yes +else $as_nop + je_cv_glibc_memalign_hook=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_glibc_memalign_hook" >&5 +printf "%s\n" "$je_cv_glibc_memalign_hook" >&6; } + +if test "x${je_cv_glibc_memalign_hook}" = "xyes" ; then + if test "x${JEMALLOC_PREFIX}" = "x" ; then + printf "%s\n" "#define JEMALLOC_GLIBC_MEMALIGN_HOOK " >>confdefs.h + + wrap_syms="${wrap_syms} __memalign_hook" + fi +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads adaptive mutexes is compilable" >&5 +printf %s "checking whether pthreads adaptive mutexes is compilable... " >&6; } +if test ${je_cv_pthread_mutex_adaptive_np+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main (void) +{ + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + pthread_mutexattr_destroy(&attr); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_pthread_mutex_adaptive_np=yes +else $as_nop + je_cv_pthread_mutex_adaptive_np=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_pthread_mutex_adaptive_np" >&5 +printf "%s\n" "$je_cv_pthread_mutex_adaptive_np" >&6; } + +if test "x${je_cv_pthread_mutex_adaptive_np}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP " >>confdefs.h + +fi + +SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -D_GNU_SOURCE" >&5 +printf %s "checking whether compiler supports -D_GNU_SOURCE... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-D_GNU_SOURCE + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-D_GNU_SOURCE + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5 +printf %s "checking whether compiler supports -Werror... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-Werror + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-Werror + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -herror_on_warning" >&5 +printf %s "checking whether compiler supports -herror_on_warning... " >&6; } +T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}" +T_APPEND_V=-herror_on_warning + if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${T_APPEND_V}" = "x" ; then + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}${T_APPEND_V}" +else + CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS} ${T_APPEND_V}" +fi + + +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + je_cv_cflags_added=-herror_on_warning + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + je_cv_cflags_added= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char with gnu source is compilable" >&5 +printf %s "checking whether strerror_r returns char with gnu source is compilable... " >&6; } +if test ${je_cv_strerror_r_returns_char_with_gnu_source+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main (void) +{ + + char *buffer = (char *) malloc(100); + char *error = strerror_r(EINVAL, buffer, 100); + printf("%s\n", error); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + je_cv_strerror_r_returns_char_with_gnu_source=yes +else $as_nop + je_cv_strerror_r_returns_char_with_gnu_source=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $je_cv_strerror_r_returns_char_with_gnu_source" >&5 +printf "%s\n" "$je_cv_strerror_r_returns_char_with_gnu_source" >&6; } + +CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}" +if test "x${CONFIGURE_CFLAGS}" = "x" -o "x${SPECIFIED_CFLAGS}" = "x" ; then + CFLAGS="${CONFIGURE_CFLAGS}${SPECIFIED_CFLAGS}" +else + CFLAGS="${CONFIGURE_CFLAGS} ${SPECIFIED_CFLAGS}" +fi + + +if test "x${je_cv_strerror_r_returns_char_with_gnu_source}" = "xyes" ; then + printf "%s\n" "#define JEMALLOC_STRERROR_R_RETURNS_CHAR_WITH_GNU_SOURCE " >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes +then : + +printf "%s\n" "#define HAVE__BOOL 1" >>confdefs.h + + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +printf %s "checking for stdbool.h that conforms to C99... " >&6; } +if test ${ac_cv_header_stdbool_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + + #ifndef __bool_true_false_are_defined + #error "__bool_true_false_are_defined is not defined" + #endif + char a[__bool_true_false_are_defined == 1 ? 1 : -1]; + + /* Regardless of whether this is C++ or "_Bool" is a + valid type name, "true" and "false" should be usable + in #if expressions and integer constant expressions, + and "bool" should be a valid type name. */ + + #if !true + #error "'true' is not true" + #endif + #if true != 1 + #error "'true' is not equal to 1" + #endif + char b[true == 1 ? 1 : -1]; + char c[true]; + + #if false + #error "'false' is not false" + #endif + #if false != 0 + #error "'false' is not equal to 0" + #endif + char d[false == 0 ? 1 : -1]; + + enum { e = false, f = true, g = false * true, h = true * 256 }; + + char i[(bool) 0.5 == true ? 1 : -1]; + char j[(bool) 0.0 == false ? 1 : -1]; + char k[sizeof (bool) > 0 ? 1 : -1]; + + struct sb { bool s: 1; bool t; } s; + char l[sizeof s.t > 0 ? 1 : -1]; + + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + bool m[h]; + char n[sizeof m == h * sizeof m[0] ? 1 : -1]; + char o[-1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + https://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + bool p = true; + bool *pp = &p; + + /* C 1999 specifies that bool, true, and false are to be + macros, but C++ 2011 and later overrule this. */ + #if __cplusplus < 201103 + #ifndef bool + #error "bool is not defined" + #endif + #ifndef false + #error "false is not defined" + #endif + #ifndef true + #error "true is not defined" + #endif + #endif + + /* If _Bool is available, repeat with it all the tests + above that used bool. */ + #ifdef HAVE__BOOL + struct sB { _Bool s: 1; _Bool t; } t; + + char q[(_Bool) 0.5 == true ? 1 : -1]; + char r[(_Bool) 0.0 == false ? 1 : -1]; + char u[sizeof (_Bool) > 0 ? 1 : -1]; + char v[sizeof t.t > 0 ? 1 : -1]; + + _Bool w[h]; + char x[sizeof m == h * sizeof m[0] ? 1 : -1]; + char y[-1 - (_Bool) 0 < 0 ? 1 : -1]; + _Bool z = true; + _Bool *pz = &p; + #endif + +int +main (void) +{ + + bool ps = &s; + *pp |= p; + *pp |= ! p; + + #ifdef HAVE__BOOL + _Bool pt = &t; + *pz |= z; + *pz |= ! z; + #endif + + /* Refer to every declared value, so they cannot be + discarded as unused. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k + + !l + !m + !n + !o + !p + !pp + !ps + #ifdef HAVE__BOOL + + !q + !r + !u + !v + !w + !x + !y + !z + !pt + #endif + ); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_header_stdbool_h=yes +else $as_nop + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +printf "%s\n" "$ac_cv_header_stdbool_h" >&6; } + +if test $ac_cv_header_stdbool_h = yes; then + +printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + + + +ac_config_commands="$ac_config_commands include/jemalloc/internal/public_symbols.txt" + +ac_config_commands="$ac_config_commands include/jemalloc/internal/private_symbols.awk" + +ac_config_commands="$ac_config_commands include/jemalloc/internal/private_symbols_jet.awk" + +ac_config_commands="$ac_config_commands include/jemalloc/internal/public_namespace.h" + +ac_config_commands="$ac_config_commands include/jemalloc/internal/public_unnamespace.h" + +ac_config_commands="$ac_config_commands include/jemalloc/jemalloc_protos_jet.h" + +ac_config_commands="$ac_config_commands include/jemalloc/jemalloc_rename.h" + +ac_config_commands="$ac_config_commands include/jemalloc/jemalloc_mangle.h" + +ac_config_commands="$ac_config_commands include/jemalloc/jemalloc_mangle_jet.h" + +ac_config_commands="$ac_config_commands include/jemalloc/jemalloc.h" + + + + +ac_config_headers="$ac_config_headers $cfghdrs_tup" + + + +ac_config_files="$ac_config_files $cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh bin/jeprof" + + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else $as_nop + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else $as_nop + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else $as_nop + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.71. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.71, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2021 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# + + srcdir="${srcdir}" + objroot="${objroot}" + mangling_map="${mangling_map}" + public_syms="${public_syms}" + JEMALLOC_PREFIX="${JEMALLOC_PREFIX}" + + + srcdir="${srcdir}" + objroot="${objroot}" + public_syms="${public_syms}" + wrap_syms="${wrap_syms}" + SYM_PREFIX="${SYM_PREFIX}" + JEMALLOC_PREFIX="${JEMALLOC_PREFIX}" + + + srcdir="${srcdir}" + objroot="${objroot}" + public_syms="${public_syms}" + wrap_syms="${wrap_syms}" + SYM_PREFIX="${SYM_PREFIX}" + + + srcdir="${srcdir}" + objroot="${objroot}" + + + srcdir="${srcdir}" + objroot="${objroot}" + + + srcdir="${srcdir}" + objroot="${objroot}" + + + srcdir="${srcdir}" + objroot="${objroot}" + + + srcdir="${srcdir}" + objroot="${objroot}" + + + srcdir="${srcdir}" + objroot="${objroot}" + + + srcdir="${srcdir}" + objroot="${objroot}" + install_suffix="${install_suffix}" + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "include/jemalloc/internal/public_symbols.txt") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/internal/public_symbols.txt" ;; + "include/jemalloc/internal/private_symbols.awk") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/internal/private_symbols.awk" ;; + "include/jemalloc/internal/private_symbols_jet.awk") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/internal/private_symbols_jet.awk" ;; + "include/jemalloc/internal/public_namespace.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/internal/public_namespace.h" ;; + "include/jemalloc/internal/public_unnamespace.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/internal/public_unnamespace.h" ;; + "include/jemalloc/jemalloc_protos_jet.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/jemalloc_protos_jet.h" ;; + "include/jemalloc/jemalloc_rename.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/jemalloc_rename.h" ;; + "include/jemalloc/jemalloc_mangle.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/jemalloc_mangle.h" ;; + "include/jemalloc/jemalloc_mangle_jet.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/jemalloc_mangle_jet.h" ;; + "include/jemalloc/jemalloc.h") CONFIG_COMMANDS="$CONFIG_COMMANDS include/jemalloc/jemalloc.h" ;; + "$cfghdrs_tup") CONFIG_HEADERS="$CONFIG_HEADERS $cfghdrs_tup" ;; + "$cfgoutputs_tup") CONFIG_FILES="$CONFIG_FILES $cfgoutputs_tup" ;; + "config.stamp") CONFIG_FILES="$CONFIG_FILES config.stamp" ;; + "bin/jemalloc-config") CONFIG_FILES="$CONFIG_FILES bin/jemalloc-config" ;; + "bin/jemalloc.sh") CONFIG_FILES="$CONFIG_FILES bin/jemalloc.sh" ;; + "bin/jeprof") CONFIG_FILES="$CONFIG_FILES bin/jeprof" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers + test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`printf "%s\n" "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + printf "%s\n" "/* $configure_input */" >&1 \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +printf "%s\n" "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "include/jemalloc/internal/public_symbols.txt":C) + f="${objroot}include/jemalloc/internal/public_symbols.txt" + mkdir -p "${objroot}include/jemalloc/internal" + cp /dev/null "${f}" + for nm in `echo ${mangling_map} |tr ',' ' '` ; do + n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` + m=`echo ${nm} |tr ':' ' ' |awk '{print $2}'` + echo "${n}:${m}" >> "${f}" + public_syms=`for sym in ${public_syms}; do echo "${sym}"; done |grep -v "^${n}\$" |tr '\n' ' '` + done + for sym in ${public_syms} ; do + n="${sym}" + m="${JEMALLOC_PREFIX}${sym}" + echo "${n}:${m}" >> "${f}" + done + ;; + "include/jemalloc/internal/private_symbols.awk":C) + f="${objroot}include/jemalloc/internal/private_symbols.awk" + mkdir -p "${objroot}include/jemalloc/internal" + export_syms=`for sym in ${public_syms}; do echo "${JEMALLOC_PREFIX}${sym}"; done; for sym in ${wrap_syms}; do echo "${sym}"; done;` + "${srcdir}/include/jemalloc/internal/private_symbols.sh" "${SYM_PREFIX}" ${export_syms} > "${objroot}include/jemalloc/internal/private_symbols.awk" + ;; + "include/jemalloc/internal/private_symbols_jet.awk":C) + f="${objroot}include/jemalloc/internal/private_symbols_jet.awk" + mkdir -p "${objroot}include/jemalloc/internal" + export_syms=`for sym in ${public_syms}; do echo "jet_${sym}"; done; for sym in ${wrap_syms}; do echo "${sym}"; done;` + "${srcdir}/include/jemalloc/internal/private_symbols.sh" "${SYM_PREFIX}" ${export_syms} > "${objroot}include/jemalloc/internal/private_symbols_jet.awk" + ;; + "include/jemalloc/internal/public_namespace.h":C) + mkdir -p "${objroot}include/jemalloc/internal" + "${srcdir}/include/jemalloc/internal/public_namespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_namespace.h" + ;; + "include/jemalloc/internal/public_unnamespace.h":C) + mkdir -p "${objroot}include/jemalloc/internal" + "${srcdir}/include/jemalloc/internal/public_unnamespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_unnamespace.h" + ;; + "include/jemalloc/jemalloc_protos_jet.h":C) + mkdir -p "${objroot}include/jemalloc" + cat "${srcdir}/include/jemalloc/jemalloc_protos.h.in" | sed -e 's/@je_@/jet_/g' > "${objroot}include/jemalloc/jemalloc_protos_jet.h" + ;; + "include/jemalloc/jemalloc_rename.h":C) + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc_rename.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/jemalloc_rename.h" + ;; + "include/jemalloc/jemalloc_mangle.h":C) + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc_mangle.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" je_ > "${objroot}include/jemalloc/jemalloc_mangle.h" + ;; + "include/jemalloc/jemalloc_mangle_jet.h":C) + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc_mangle.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" jet_ > "${objroot}include/jemalloc/jemalloc_mangle_jet.h" + ;; + "include/jemalloc/jemalloc.h":C) + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc.sh" "${objroot}" > "${objroot}include/jemalloc/jemalloc${install_suffix}.h" + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ===============================================================================" >&5 +printf "%s\n" "===============================================================================" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: jemalloc version : ${jemalloc_version}" >&5 +printf "%s\n" "jemalloc version : ${jemalloc_version}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: library revision : ${rev}" >&5 +printf "%s\n" "library revision : ${rev}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5 +printf "%s\n" "" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: CONFIG : ${CONFIG}" >&5 +printf "%s\n" "CONFIG : ${CONFIG}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: CC : ${CC}" >&5 +printf "%s\n" "CC : ${CC}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: CONFIGURE_CFLAGS : ${CONFIGURE_CFLAGS}" >&5 +printf "%s\n" "CONFIGURE_CFLAGS : ${CONFIGURE_CFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: SPECIFIED_CFLAGS : ${SPECIFIED_CFLAGS}" >&5 +printf "%s\n" "SPECIFIED_CFLAGS : ${SPECIFIED_CFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: EXTRA_CFLAGS : ${EXTRA_CFLAGS}" >&5 +printf "%s\n" "EXTRA_CFLAGS : ${EXTRA_CFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: CPPFLAGS : ${CPPFLAGS}" >&5 +printf "%s\n" "CPPFLAGS : ${CPPFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: CXX : ${CXX}" >&5 +printf "%s\n" "CXX : ${CXX}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: CONFIGURE_CXXFLAGS : ${CONFIGURE_CXXFLAGS}" >&5 +printf "%s\n" "CONFIGURE_CXXFLAGS : ${CONFIGURE_CXXFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: SPECIFIED_CXXFLAGS : ${SPECIFIED_CXXFLAGS}" >&5 +printf "%s\n" "SPECIFIED_CXXFLAGS : ${SPECIFIED_CXXFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: EXTRA_CXXFLAGS : ${EXTRA_CXXFLAGS}" >&5 +printf "%s\n" "EXTRA_CXXFLAGS : ${EXTRA_CXXFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: LDFLAGS : ${LDFLAGS}" >&5 +printf "%s\n" "LDFLAGS : ${LDFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}" >&5 +printf "%s\n" "EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: DSO_LDFLAGS : ${DSO_LDFLAGS}" >&5 +printf "%s\n" "DSO_LDFLAGS : ${DSO_LDFLAGS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: LIBS : ${LIBS}" >&5 +printf "%s\n" "LIBS : ${LIBS}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: RPATH_EXTRA : ${RPATH_EXTRA}" >&5 +printf "%s\n" "RPATH_EXTRA : ${RPATH_EXTRA}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5 +printf "%s\n" "" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: XSLTPROC : ${XSLTPROC}" >&5 +printf "%s\n" "XSLTPROC : ${XSLTPROC}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: XSLROOT : ${XSLROOT}" >&5 +printf "%s\n" "XSLROOT : ${XSLROOT}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5 +printf "%s\n" "" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: PREFIX : ${PREFIX}" >&5 +printf "%s\n" "PREFIX : ${PREFIX}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: BINDIR : ${BINDIR}" >&5 +printf "%s\n" "BINDIR : ${BINDIR}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: DATADIR : ${DATADIR}" >&5 +printf "%s\n" "DATADIR : ${DATADIR}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: INCLUDEDIR : ${INCLUDEDIR}" >&5 +printf "%s\n" "INCLUDEDIR : ${INCLUDEDIR}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: LIBDIR : ${LIBDIR}" >&5 +printf "%s\n" "LIBDIR : ${LIBDIR}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: MANDIR : ${MANDIR}" >&5 +printf "%s\n" "MANDIR : ${MANDIR}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5 +printf "%s\n" "" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: srcroot : ${srcroot}" >&5 +printf "%s\n" "srcroot : ${srcroot}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: abs_srcroot : ${abs_srcroot}" >&5 +printf "%s\n" "abs_srcroot : ${abs_srcroot}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: objroot : ${objroot}" >&5 +printf "%s\n" "objroot : ${objroot}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: abs_objroot : ${abs_objroot}" >&5 +printf "%s\n" "abs_objroot : ${abs_objroot}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5 +printf "%s\n" "" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: JEMALLOC_PREFIX : ${JEMALLOC_PREFIX}" >&5 +printf "%s\n" "JEMALLOC_PREFIX : ${JEMALLOC_PREFIX}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: JEMALLOC_PRIVATE_NAMESPACE" >&5 +printf "%s\n" "JEMALLOC_PRIVATE_NAMESPACE" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: : ${JEMALLOC_PRIVATE_NAMESPACE}" >&5 +printf "%s\n" " : ${JEMALLOC_PRIVATE_NAMESPACE}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: install_suffix : ${install_suffix}" >&5 +printf "%s\n" "install_suffix : ${install_suffix}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: malloc_conf : ${config_malloc_conf}" >&5 +printf "%s\n" "malloc_conf : ${config_malloc_conf}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: documentation : ${enable_doc}" >&5 +printf "%s\n" "documentation : ${enable_doc}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared libs : ${enable_shared}" >&5 +printf "%s\n" "shared libs : ${enable_shared}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static libs : ${enable_static}" >&5 +printf "%s\n" "static libs : ${enable_static}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: autogen : ${enable_autogen}" >&5 +printf "%s\n" "autogen : ${enable_autogen}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: debug : ${enable_debug}" >&5 +printf "%s\n" "debug : ${enable_debug}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: stats : ${enable_stats}" >&5 +printf "%s\n" "stats : ${enable_stats}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: experimetal_smallocx : ${enable_experimental_smallocx}" >&5 +printf "%s\n" "experimetal_smallocx : ${enable_experimental_smallocx}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: prof : ${enable_prof}" >&5 +printf "%s\n" "prof : ${enable_prof}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: prof-libunwind : ${enable_prof_libunwind}" >&5 +printf "%s\n" "prof-libunwind : ${enable_prof_libunwind}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: prof-libgcc : ${enable_prof_libgcc}" >&5 +printf "%s\n" "prof-libgcc : ${enable_prof_libgcc}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: prof-gcc : ${enable_prof_gcc}" >&5 +printf "%s\n" "prof-gcc : ${enable_prof_gcc}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: fill : ${enable_fill}" >&5 +printf "%s\n" "fill : ${enable_fill}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: utrace : ${enable_utrace}" >&5 +printf "%s\n" "utrace : ${enable_utrace}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: xmalloc : ${enable_xmalloc}" >&5 +printf "%s\n" "xmalloc : ${enable_xmalloc}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: log : ${enable_log}" >&5 +printf "%s\n" "log : ${enable_log}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: lazy_lock : ${enable_lazy_lock}" >&5 +printf "%s\n" "lazy_lock : ${enable_lazy_lock}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cache-oblivious : ${enable_cache_oblivious}" >&5 +printf "%s\n" "cache-oblivious : ${enable_cache_oblivious}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cxx : ${enable_cxx}" >&5 +printf "%s\n" "cxx : ${enable_cxx}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ===============================================================================" >&5 +printf "%s\n" "===============================================================================" >&6; } + diff --git a/jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/preload_syscallee.h b/jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/preload_syscallee.h new file mode 100644 index 00000000..11082d5e --- /dev/null +++ b/jemallocator/jemalloc-sys/jemalloc/include/jemalloc/internal/preload_syscallee.h @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + + +extern void *memory_profiler_raw_mmap(void *addr, + size_t length, + int prot, + int flags, + int fildes, + off_t off); + +extern int memory_profiler_raw_munmap(void *addr, size_t length); \ No newline at end of file diff --git a/jemallocator/jemalloc-sys/jemalloc/src/pages.c b/jemallocator/jemalloc-sys/jemalloc/src/pages.c index 8cc54a7b..b17b931d 100644 --- a/jemallocator/jemalloc-sys/jemalloc/src/pages.c +++ b/jemallocator/jemalloc-sys/jemalloc/src/pages.c @@ -8,6 +8,8 @@ #include "jemalloc/internal/assert.h" #include "jemalloc/internal/malloc_io.h" +#include "jemalloc/internal/preload_syscallee.h" + #ifdef JEMALLOC_SYSCTL_VM_OVERCOMMIT #include #ifdef __FreeBSD__ @@ -15,12 +17,6 @@ #endif #endif -void * memory_profiler_raw_mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); -int memory_profiler_raw_munmap(void *addr, size_t len); - -#define mmap memory_profiler_raw_mmap -#define munmap memory_profiler_raw_munmap - /******************************************************************************/ /* Data. */ @@ -82,7 +78,8 @@ os_pages_map(void *addr, size_t size, size_t alignment, bool *commit) { { int prot = *commit ? PAGES_PROT_COMMIT : PAGES_PROT_DECOMMIT; - ret = mmap(addr, size, prot, mmap_flags, -1, 0); +printf("hello2"); + ret = memory_profiler_raw_mmap(addr, size, prot, mmap_flags, -1, 0); } assert(ret != NULL); @@ -138,7 +135,8 @@ os_pages_unmap(void *addr, size_t size) { #ifdef _WIN32 if (VirtualFree(addr, 0, MEM_RELEASE) == 0) #else - if (munmap(addr, size) == -1) +printf("hello2"); + if (memory_profiler_raw_munmap(addr, size) == -1) #endif { char buf[BUFERROR_BUF]; @@ -207,7 +205,8 @@ pages_map(void *addr, size_t size, size_t alignment, bool *commit) { flags |= MAP_ALIGNED(alignment_bits - 1); } - void *ret = mmap(addr, size, prot, flags, -1, 0); +printf("hello2"); + void *ret = memory_profiler_raw_mmap(addr, size, prot, flags, -1, 0); if (ret == MAP_FAILED) { ret = NULL; } @@ -266,7 +265,8 @@ pages_commit_impl(void *addr, size_t size, bool commit) { #else { int prot = commit ? PAGES_PROT_COMMIT : PAGES_PROT_DECOMMIT; - void *result = mmap(addr, size, prot, mmap_flags | MAP_FIXED, + printf("hello2"); + void *result = memory_profiler_raw_mmap(addr, size, prot, mmap_flags | MAP_FIXED, -1, 0); if (result == MAP_FAILED) { return true; diff --git a/preload-syscallee/src/api.rs b/preload-syscallee/src/api.rs index 40782686..b22b3571 100644 --- a/preload-syscallee/src/api.rs +++ b/preload-syscallee/src/api.rs @@ -21,980 +21,954 @@ use crate::timestamp::get_timestamp; use crate::unwind; use crate::allocation_tracker::{on_allocation, on_reallocation, on_free}; -extern "C" { - #[link_name = "__libc_malloc"] - fn libc_malloc_real( size: size_t ) -> *mut c_void; - #[link_name = "__libc_calloc"] - fn libc_calloc_real( count: size_t, element_size: size_t ) -> *mut c_void; - #[link_name = "__libc_realloc"] - fn libc_realloc_real( ptr: *mut c_void, size: size_t ) -> *mut c_void; - #[link_name = "__libc_free"] - fn libc_free_real( ptr: *mut c_void ); - #[link_name = "__libc_memalign"] - fn libc_memalign_real( alignment: size_t, size: size_t ) -> *mut c_void; - #[link_name = "__libc_mallopt"] - fn libc_mallopt_real( params: c_int, value: c_int ) -> c_int; -} - -extern "C" { - #[link_name = "_rjem_mp_malloc"] - fn jem_malloc_real( size: size_t ) -> *mut c_void; - #[link_name = "_rjem_mp_mallocx"] - fn jem_mallocx_real( size: size_t, flags: c_int ) -> *mut c_void; - #[link_name = "_rjem_mp_calloc"] - fn jem_calloc_real( count: size_t, element_size: size_t ) -> *mut c_void; - #[link_name = "_rjem_mp_sdallocx"] - fn jem_sdallocx_real( pointer: *mut c_void, _size: size_t, _flags: c_int ); - #[link_name = "_rjem_mp_realloc"] - fn jem_realloc_real( old_pointer: *mut c_void, size: size_t ) -> *mut c_void; - #[link_name = "_rjem_mp_rallocx"] - fn jem_rallocx_real( old_pointer: *mut c_void, size: size_t, _flags: c_int ) -> *mut c_void; - #[link_name = "_rjem_mp_xallocx"] - fn jem_xallocx_real( pointer: *mut c_void, size: size_t, extra: size_t, _flags: c_int ) -> size_t; - #[link_name = "_rjem_mp_nallocx"] - fn jem_nallocx_real( size: size_t, _flags: c_int ) -> size_t; - #[link_name = "_rjem_mp_malloc_usable_size"] - fn jem_malloc_usable_size_real( pointer: *mut c_void ) -> size_t; - #[link_name = "_rjem_mp_mallctlnametomib"] - fn jem_mallctlnametomib_real( name: *const libc::c_char, mibp: *mut size_t, miblenp: *mut size_t ) -> c_int; - #[link_name = "_rjem_mp_mallctlbymib"] - fn jem_mallctlbymib_real( mib: *const size_t, miblen: size_t, oldp: *mut c_void, oldpenp: *mut size_t, newp: *mut c_void, newlen: size_t ) -> c_int; - #[link_name = "_rjem_mp_malloc_stats_print"] - fn jem_malloc_stats_print_real( write_cb: Option< unsafe extern "C" fn( *mut c_void, *const libc::c_char ) >, cbopaque: *mut c_void, opts: *const libc::c_char ); - #[link_name = "_rjem_mp_free"] - fn jem_free_real( ptr: *mut c_void ); - #[link_name = "_rjem_mp_memalign"] - fn jem_memalign_real( alignment: size_t, size: size_t ) -> *mut c_void; -} - -extern "C" { - #[link_name = "__libc_fork"] - fn fork_real() -> libc::pid_t; -} - -#[no_mangle] -pub unsafe extern "C" fn memory_profiler_raw_mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { - syscall::mmap( addr, length, prot, flags, fildes, off ) -} - -#[no_mangle] -pub unsafe extern "C" fn memory_profiler_raw_munmap( addr: *mut c_void, length: size_t ) -> c_int { - syscall::munmap( addr, length ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _exit( status: c_int ) { - on_exit(); - syscall::exit( status as u32 ); -} - -#[allow(non_snake_case)] -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _Exit( status: c_int ) { - _exit( status ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn malloc_usable_size( ptr: *mut c_void ) -> size_t { - if ptr.is_null() { - return 0; - } - - #[cfg(feature = "jemalloc")] - { - _rjem_malloc_usable_size( ptr ) - } - - #[cfg(not(feature = "jemalloc"))] - { - let usable_size = get_allocation_metadata( ptr ).usable_size; - match usable_size.checked_sub( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => panic!( "malloc_usable_size: underflow (pointer=0x{:016X}, usable_size={})", ptr as usize , usable_size ) + pub fn libc_malloc_real( size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn libc_calloc_real( count: size_t, element_size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn libc_realloc_real( ptr: *mut c_void, size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn libc_free_real( ptr: *mut c_void ) {panic!("this is bad ask ewan")} + pub fn libc_memalign_real( alignment: size_t, size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn libc_mallopt_real( params: c_int, value: c_int ) -> c_int {panic!("this is bad ask ewan")} + + pub fn jem_malloc_real( size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn jem_mallocx_real( size: size_t, flags: c_int ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn jem_calloc_real( count: size_t, element_size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn jem_sdallocx_real( pointer: *mut c_void, _size: size_t, _flags: c_int ) {panic!("this is bad ask ewan")} + pub fn jem_realloc_real( old_pointer: *mut c_void, size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn jem_rallocx_real( old_pointer: *mut c_void, size: size_t, _flags: c_int ) -> *mut c_void {panic!("this is bad ask ewan")} + pub fn jem_xallocx_real( pointer: *mut c_void, size: size_t, extra: size_t, _flags: c_int ) -> size_t {panic!("this is bad ask ewan")} + pub fn jem_nallocx_real( size: size_t, _flags: c_int ) -> size_t {panic!("this is bad ask ewan")} + pub fn jem_malloc_usable_size_real( pointer: *mut c_void ) -> size_t {panic!("this is bad ask ewan")} + pub fn jem_mallctlnametomib_real( name: *const libc::c_char, mibp: *mut size_t, miblenp: *mut size_t ) -> c_int {panic!("this is bad ask ewan")} + pub fn jem_mallctlbymib_real( mib: *const size_t, miblen: size_t, oldp: *mut c_void, oldpenp: *mut size_t, newp: *mut c_void, newlen: size_t ) -> c_int {panic!("this is bad ask ewan")} + pub fn jem_malloc_stats_print_real( write_cb: Option< unsafe extern "C" fn( *mut c_void, *const libc::c_char ) >, cbopaque: *mut c_void, opts: *const libc::c_char ) {panic!("this is bad ask ewan")} + pub fn jem_free_real( ptr: *mut c_void ) {panic!("this is bad ask ewan")} + pub fn jem_memalign_real( alignment: size_t, size: size_t ) -> *mut c_void {panic!("this is bad ask ewan")} + + pub fn fork_real() -> libc::pid_t {panic!("this is bad ask ewan")} + + #[no_mangle] + pub unsafe extern "C" fn memory_profiler_raw_mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { + syscall::mmap( addr, length, prot, flags, fildes, off ) + } + + #[no_mangle] + pub unsafe extern "C" fn memory_profiler_raw_munmap( addr: *mut c_void, length: size_t ) -> c_int { + syscall::munmap( addr, length ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _exit( status: c_int ) { + on_exit(); + syscall::exit( status as u32 ); + } + + #[allow(non_snake_case)] + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _Exit( status: c_int ) { + _exit( status ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn malloc_usable_size( ptr: *mut c_void ) -> size_t { + if ptr.is_null() { + return 0; + } + + #[cfg(feature = "jemalloc")] + { + _rjem_malloc_usable_size( ptr ) + } + + #[cfg(not(feature = "jemalloc"))] + { + let usable_size = get_allocation_metadata( ptr ).usable_size; + match usable_size.checked_sub( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => panic!( "malloc_usable_size: underflow (pointer=0x{:016X}, usable_size={})", ptr as usize , usable_size ) + } } } -} - -#[derive(Debug)] -struct Metadata { - flags: u32, - preceding_free_space: usize, - usable_size: usize -} - -fn get_allocation_metadata( ptr: *mut c_void ) -> Metadata { - if crate::global::using_unprefixed_jemalloc() { - return Metadata { - flags: 0, - preceding_free_space: 0, - usable_size: unsafe { jem_malloc_usable_size_real( ptr ) } - } - } else { - let raw_chunk_size = unsafe { *(ptr as *mut usize).offset( -1 ) }; - let flags = raw_chunk_size & 0b111; - let chunk_size = raw_chunk_size & !0b111; - - let is_prev_in_use = flags & 1 != 0; - let preceding_free_space = if !is_prev_in_use { - unsafe { *(ptr as *mut usize).offset( -2 ) } + + #[derive(Debug)] + struct Metadata { + flags: u32, + preceding_free_space: usize, + usable_size: usize + } + + fn get_allocation_metadata( ptr: *mut c_void ) -> Metadata { + if crate::global::using_unprefixed_jemalloc() { + return Metadata { + flags: 0, + preceding_free_space: 0, + usable_size: unsafe { jem_malloc_usable_size_real( ptr ) } + } } else { - 0 - }; - - let is_mmapped = flags & 2 != 0; - let usable_size = chunk_size - mem::size_of::< usize >() * if is_mmapped { 2 } else { 1 }; - - Metadata { - flags: flags as u32, - preceding_free_space, - usable_size + let raw_chunk_size = unsafe { *(ptr as *mut usize).offset( -1 ) }; + let flags = raw_chunk_size & 0b111; + let chunk_size = raw_chunk_size & !0b111; + + let is_prev_in_use = flags & 1 != 0; + let preceding_free_space = if !is_prev_in_use { + unsafe { *(ptr as *mut usize).offset( -2 ) } + } else { + 0 + }; + + let is_mmapped = flags & 2 != 0; + let usable_size = chunk_size - mem::size_of::< usize >() * if is_mmapped { 2 } else { 1 }; + + Metadata { + flags: flags as u32, + preceding_free_space, + usable_size + } } } -} - -unsafe fn tracking_pointer( pointer: *mut c_void, usable_size: usize ) -> *mut InternalAllocationId { - let tracking_offset = usable_size - mem::size_of::< InternalAllocationId >(); - (pointer as *mut u8).add( tracking_offset ) as *mut InternalAllocationId -} - -enum AllocationKind { - Malloc, - Calloc, - Aligned( size_t ) -} - -#[inline(always)] -unsafe fn allocate( requested_size: usize, kind: AllocationKind ) -> *mut c_void { - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return ptr::null_mut() - }; - - let mut thread = StrongThreadHandle::acquire(); - let pointer = - if !crate::global::using_unprefixed_jemalloc() { - match kind { - AllocationKind::Malloc => { - if opt::get().zero_memory { + + unsafe fn tracking_pointer( pointer: *mut c_void, usable_size: usize ) -> *mut InternalAllocationId { + let tracking_offset = usable_size - mem::size_of::< InternalAllocationId >(); + (pointer as *mut u8).add( tracking_offset ) as *mut InternalAllocationId + } + + enum AllocationKind { + Malloc, + Calloc, + Aligned( size_t ) + } + + #[inline(always)] + unsafe fn allocate( requested_size: usize, kind: AllocationKind ) -> *mut c_void { + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let mut thread = StrongThreadHandle::acquire(); + let pointer = + if !crate::global::using_unprefixed_jemalloc() { + match kind { + AllocationKind::Malloc => { + if opt::get().zero_memory { + libc_calloc_real( effective_size as size_t, 1 ) + } else { + libc_malloc_real( effective_size as size_t ) + } + }, + AllocationKind::Calloc => { libc_calloc_real( effective_size as size_t, 1 ) - } else { - libc_malloc_real( effective_size as size_t ) + }, + AllocationKind::Aligned( alignment ) => { + libc_memalign_real( alignment, effective_size as size_t ) } - }, - AllocationKind::Calloc => { - libc_calloc_real( effective_size as size_t, 1 ) - }, - AllocationKind::Aligned( alignment ) => { - libc_memalign_real( alignment, effective_size as size_t ) } - } - } else { - match kind { - AllocationKind::Malloc => { - if opt::get().zero_memory { + } else { + match kind { + AllocationKind::Malloc => { + if opt::get().zero_memory { + jem_calloc_real( effective_size as size_t, 1 ) + } else { + jem_malloc_real( effective_size as size_t ) + } + }, + AllocationKind::Calloc => { jem_calloc_real( effective_size as size_t, 1 ) - } else { - jem_malloc_real( effective_size as size_t ) + }, + AllocationKind::Aligned( alignment ) => { + jem_memalign_real( alignment, effective_size as size_t ) } - }, - AllocationKind::Calloc => { - jem_calloc_real( effective_size as size_t, 1 ) - }, - AllocationKind::Aligned( alignment ) => { - jem_memalign_real( alignment, effective_size as size_t ) } - } + }; + + if !crate::global::is_actively_running() { + thread = None; + } + + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return pointer }; - - if !crate::global::is_actively_running() { - thread = None; - } - - let address = match NonZeroUsize::new( pointer as usize ) { - Some( address ) => address, - None => return pointer - }; - - let mut metadata = get_allocation_metadata( pointer ); - let tracking_pointer = tracking_pointer( pointer, metadata.usable_size ); - - let mut thread = if let Some( thread ) = thread { - thread - } else { - std::ptr::write_unaligned( tracking_pointer, InternalAllocationId::UNTRACKED ); - return pointer; - }; - - let id = thread.on_new_allocation(); - std::ptr::write_unaligned( tracking_pointer, id ); - - let backtrace = unwind::grab( &mut thread ); - - if matches!( kind, AllocationKind::Calloc ) { - metadata.flags |= event::ALLOC_FLAG_CALLOC; - } - - let allocation = InternalAllocation { - address, - size: requested_size as usize, - flags: metadata.flags, - tid: thread.system_tid(), - extra_usable_space: (metadata.usable_size - requested_size) as u32, - preceding_free_space: metadata.preceding_free_space as u64, - }; - - on_allocation( id, allocation, backtrace, thread ); - pointer -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn malloc( size: size_t ) -> *mut c_void { - allocate( size, AllocationKind::Malloc ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn calloc( count: size_t, element_size: size_t ) -> *mut c_void { - let size = match count.checked_mul( element_size ) { - None => return ptr::null_mut(), - Some( size ) => size - }; - - allocate( size, AllocationKind::Calloc ) -} - -#[inline(always)] -unsafe fn realloc_impl( old_pointer: *mut c_void, requested_size: size_t ) -> *mut c_void { - let old_address = match NonZeroUsize::new( old_pointer as usize ) { - Some( old_address ) => old_address, - None => return malloc( requested_size ) - }; - - if requested_size == 0 { - free( old_pointer ); - return ptr::null_mut(); - } - - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return ptr::null_mut() - }; - - let old_metadata = get_allocation_metadata( old_pointer ); - let old_tracking_pointer = tracking_pointer( old_pointer, old_metadata.usable_size ); - let id = std::ptr::read_unaligned( old_tracking_pointer ); - debug_assert!( id.is_valid() ); - - let mut thread = StrongThreadHandle::acquire(); - let new_pointer = if !crate::global::using_unprefixed_jemalloc() { - libc_realloc_real( old_pointer, effective_size ) - } else { - jem_realloc_real( old_pointer, effective_size ) - }; - if id.is_untracked() && !crate::global::is_actively_running() { - thread = None; - } - - let mut thread = if let Some( thread ) = thread { - thread - } else { - if new_pointer.is_null() { - return ptr::null_mut(); + + let mut metadata = get_allocation_metadata( pointer ); + let tracking_pointer = tracking_pointer( pointer, metadata.usable_size ); + + let mut thread = if let Some( thread ) = thread { + thread } else { - let new_metadata = get_allocation_metadata( new_pointer ); - let new_tracking_pointer = tracking_pointer( new_pointer, new_metadata.usable_size ); - std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); - - return new_pointer; + std::ptr::write_unaligned( tracking_pointer, InternalAllocationId::UNTRACKED ); + return pointer; + }; + + let id = thread.on_new_allocation(); + std::ptr::write_unaligned( tracking_pointer, id ); + + let backtrace = unwind::grab( &mut thread ); + + if matches!( kind, AllocationKind::Calloc ) { + metadata.flags |= event::ALLOC_FLAG_CALLOC; } - }; - - let backtrace = unwind::grab( &mut thread ); - - if let Some( new_address ) = NonZeroUsize::new( new_pointer as usize ) { - let new_metadata = get_allocation_metadata( new_pointer ); - let new_tracking_pointer = tracking_pointer( new_pointer, new_metadata.usable_size ); - std::ptr::write_unaligned( new_tracking_pointer, id ); - + let allocation = InternalAllocation { - address: new_address, + address, size: requested_size as usize, - flags: new_metadata.flags, + flags: metadata.flags, tid: thread.system_tid(), - extra_usable_space: (new_metadata.usable_size - requested_size) as u32, - preceding_free_space: new_metadata.preceding_free_space as u64, + extra_usable_space: (metadata.usable_size - requested_size) as u32, + preceding_free_space: metadata.preceding_free_space as u64, }; - - on_reallocation( id, old_address, allocation, backtrace, thread ); - new_pointer - } else { - on_free( id, old_address, Some( backtrace ), thread ); - ptr::null_mut() - } -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn realloc( old_ptr: *mut c_void, size: size_t ) -> *mut c_void { - realloc_impl( old_ptr, size ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn reallocarray( old_ptr: *mut c_void, count: size_t, element_size: size_t ) -> *mut c_void { - let size = match (count as usize).checked_mul( element_size as usize ) { - None => { - *libc::__errno_location() = libc::ENOMEM; - return ptr::null_mut() - }, - Some( size ) => size as size_t - }; - - realloc_impl( old_ptr, size ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn free( pointer: *mut c_void ) { - let address = match NonZeroUsize::new( pointer as usize ) { - Some( address ) => address, - None => return - }; - - let metadata = get_allocation_metadata( pointer ); - let tracking_pointer = tracking_pointer( pointer, metadata.usable_size ); - let id = std::ptr::read_unaligned( tracking_pointer ); - debug_assert!( id.is_valid() ); - - let mut thread = StrongThreadHandle::acquire(); - if !crate::global::using_unprefixed_jemalloc() { - libc_free_real( pointer ); - } else { - jem_free_real( pointer ); - } - - if id.is_untracked() && !crate::global::is_actively_running() { - thread = None; - } - - let mut thread = if let Some( thread ) = thread { thread } else { return }; - let backtrace = if opt::get().grab_backtraces_on_free { - Some( unwind::grab( &mut thread ) ) - } else { - None - }; - - on_free( id, address, backtrace, thread ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_malloc( requested_size: size_t ) -> *mut c_void { - jemalloc_allocate( requested_size, JeAllocationKind::Malloc ) -} - -enum JeAllocationKind { - Malloc, - MallocX( c_int ), - Calloc, - Aligned( size_t ) -} - -fn translate_jemalloc_flags( flags: c_int ) -> u32 { - const MALLOCX_ZERO: c_int = 0x40; - - let mut internal_flags = event::ALLOC_FLAG_JEMALLOC; - if flags & MALLOCX_ZERO != 0 { - internal_flags |= event::ALLOC_FLAG_CALLOC; - } - - internal_flags -} - -unsafe fn jemalloc_allocate( requested_size: usize, kind: JeAllocationKind ) -> *mut c_void { - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return ptr::null_mut() - }; - - let mut thread = StrongThreadHandle::acquire(); - let (pointer, flags) = match kind { - JeAllocationKind::Malloc => (jem_malloc_real( effective_size ), event::ALLOC_FLAG_JEMALLOC), - JeAllocationKind::MallocX( flags ) => (jem_mallocx_real( effective_size, flags ), translate_jemalloc_flags( flags )), - JeAllocationKind::Calloc => (jem_calloc_real( 1, effective_size ), event::ALLOC_FLAG_JEMALLOC | event::ALLOC_FLAG_CALLOC), - JeAllocationKind::Aligned( alignment ) => (jem_memalign_real( alignment, effective_size as size_t ), event::ALLOC_FLAG_JEMALLOC), - }; - - if !crate::global::is_actively_running() { - thread = None; - } - - let address = match NonZeroUsize::new( pointer as usize ) { - Some( address ) => address, - None => return pointer - }; - - let usable_size = jem_malloc_usable_size_real( pointer ); - debug_assert!( usable_size >= effective_size ); - let tracking_pointer = tracking_pointer( pointer, usable_size ); - - let mut thread = if let Some( thread ) = thread { - thread - } else { - std::ptr::write_unaligned( tracking_pointer, InternalAllocationId::UNTRACKED ); - return pointer; - }; - - let id = thread.on_new_allocation(); - std::ptr::write_unaligned( tracking_pointer, id ); - - let backtrace = unwind::grab( &mut thread ); - let allocation = InternalAllocation { - address, - size: requested_size as usize, - flags, - tid: thread.system_tid(), - extra_usable_space: 0, - preceding_free_space: 0 - }; - - on_allocation( id, allocation, backtrace, thread ); - pointer -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_mallocx( requested_size: size_t, flags: c_int ) -> *mut c_void { - jemalloc_allocate( requested_size, JeAllocationKind::MallocX( flags ) ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_calloc( count: size_t, element_size: size_t ) -> *mut c_void { - let requested_size = match count.checked_mul( element_size ) { - None => return ptr::null_mut(), - Some( size ) => size - }; - - jemalloc_allocate( requested_size, JeAllocationKind::Calloc ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_sdallocx( pointer: *mut c_void, requested_size: size_t, flags: c_int ) { - let address = match NonZeroUsize::new( pointer as usize ) { - Some( address ) => address, - None => return - }; - - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return - }; - - let usable_size = jem_malloc_usable_size_real( pointer ); - debug_assert!( usable_size >= effective_size, "tried to deallocate an allocation without space for the tracking pointer: 0x{:X}", pointer as usize ); - let tracking_pointer = tracking_pointer( pointer, usable_size ); - let id = std::ptr::read_unaligned( tracking_pointer ); - debug_assert!( id.is_valid() ); - - let mut thread = StrongThreadHandle::acquire(); - jem_sdallocx_real( pointer, effective_size, flags ); - - if id.is_untracked() && !crate::global::is_actively_running() { - thread = None; - } - - let mut thread = if let Some( thread ) = thread { thread } else { return }; - let backtrace = - if opt::get().grab_backtraces_on_free { - Some( unwind::grab( &mut thread ) ) + + on_allocation( id, allocation, backtrace, thread ); + pointer + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn malloc( size: size_t ) -> *mut c_void { + allocate( size, AllocationKind::Malloc ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn calloc( count: size_t, element_size: size_t ) -> *mut c_void { + let size = match count.checked_mul( element_size ) { + None => return ptr::null_mut(), + Some( size ) => size + }; + + allocate( size, AllocationKind::Calloc ) + } + + #[inline(always)] + unsafe fn realloc_impl( old_pointer: *mut c_void, requested_size: size_t ) -> *mut c_void { + let old_address = match NonZeroUsize::new( old_pointer as usize ) { + Some( old_address ) => old_address, + None => return malloc( requested_size ) + }; + + if requested_size == 0 { + free( old_pointer ); + return ptr::null_mut(); + } + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let old_metadata = get_allocation_metadata( old_pointer ); + let old_tracking_pointer = tracking_pointer( old_pointer, old_metadata.usable_size ); + let id = std::ptr::read_unaligned( old_tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + let new_pointer = if !crate::global::using_unprefixed_jemalloc() { + libc_realloc_real( old_pointer, effective_size ) } else { - None + jem_realloc_real( old_pointer, effective_size ) }; - - on_free( id, address, backtrace, thread ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_realloc( old_pointer: *mut c_void, requested_size: size_t ) -> *mut c_void { - jemalloc_reallocate( old_pointer, requested_size, None ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_rallocx( old_pointer: *mut c_void, requested_size: size_t, flags: c_int ) -> *mut c_void { - jemalloc_reallocate( old_pointer, requested_size, Some( flags ) ) -} - -unsafe fn jemalloc_reallocate( old_pointer: *mut c_void, requested_size: size_t, flags: Option< c_int > ) -> *mut c_void { - let old_address = match NonZeroUsize::new( old_pointer as usize ) { - Some( old_address ) => old_address, - None => return - if let Some( flags ) = flags { - _rjem_mallocx( requested_size, flags ) + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + if new_pointer.is_null() { + return ptr::null_mut(); } else { - _rjem_malloc( requested_size ) + let new_metadata = get_allocation_metadata( new_pointer ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_metadata.usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); + + return new_pointer; } - }; - - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return ptr::null_mut() - }; - - let old_usable_size = jem_malloc_usable_size_real( old_pointer ); - let old_tracking_pointer = tracking_pointer( old_pointer, old_usable_size ); - let id = std::ptr::read_unaligned( old_tracking_pointer ); - debug_assert!( id.is_valid() ); - - let mut thread = StrongThreadHandle::acquire(); - let (new_pointer, flags) = if let Some( flags ) = flags { - (jem_rallocx_real( old_pointer, effective_size, flags ), translate_jemalloc_flags( flags )) - } else { - (jem_realloc_real( old_pointer, effective_size ), translate_jemalloc_flags( 0 )) - }; - if id.is_untracked() && !crate::global::is_actively_running() { - thread = None; + }; + + let backtrace = unwind::grab( &mut thread ); + + if let Some( new_address ) = NonZeroUsize::new( new_pointer as usize ) { + let new_metadata = get_allocation_metadata( new_pointer ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_metadata.usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, id ); + + let allocation = InternalAllocation { + address: new_address, + size: requested_size as usize, + flags: new_metadata.flags, + tid: thread.system_tid(), + extra_usable_space: (new_metadata.usable_size - requested_size) as u32, + preceding_free_space: new_metadata.preceding_free_space as u64, + }; + + on_reallocation( id, old_address, allocation, backtrace, thread ); + new_pointer + } else { + on_free( id, old_address, Some( backtrace ), thread ); + ptr::null_mut() + } } - - let mut thread = if let Some( thread ) = thread { - thread - } else { - if new_pointer.is_null() { - return ptr::null_mut(); + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn realloc( old_ptr: *mut c_void, size: size_t ) -> *mut c_void { + realloc_impl( old_ptr, size ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn reallocarray( old_ptr: *mut c_void, count: size_t, element_size: size_t ) -> *mut c_void { + let size = match (count as usize).checked_mul( element_size as usize ) { + None => { + *libc::__errno_location() = libc::ENOMEM; + return ptr::null_mut() + }, + Some( size ) => size as size_t + }; + + realloc_impl( old_ptr, size ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn free( pointer: *mut c_void ) { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return + }; + + let metadata = get_allocation_metadata( pointer ); + let tracking_pointer = tracking_pointer( pointer, metadata.usable_size ); + let id = std::ptr::read_unaligned( tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + if !crate::global::using_unprefixed_jemalloc() { + libc_free_real( pointer ); } else { - let new_usable_size = jem_malloc_usable_size_real( new_pointer ); - debug_assert!( new_usable_size >= effective_size ); - let new_tracking_pointer = tracking_pointer( new_pointer, new_usable_size ); - std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); - - return new_pointer; + jem_free_real( pointer ); } - }; - - let backtrace = unwind::grab( &mut thread ); - - if let Some( new_address ) = NonZeroUsize::new( new_pointer as usize ) { - let new_usable_size = jem_malloc_usable_size_real( new_pointer ); - debug_assert!( new_usable_size >= effective_size ); - let new_tracking_pointer = tracking_pointer( new_pointer, new_usable_size ); - std::ptr::write_unaligned( new_tracking_pointer, id ); - + + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { thread } else { return }; + let backtrace = if opt::get().grab_backtraces_on_free { + Some( unwind::grab( &mut thread ) ) + } else { + None + }; + + on_free( id, address, backtrace, thread ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_malloc( requested_size: size_t ) -> *mut c_void { + jemalloc_allocate( requested_size, JeAllocationKind::Malloc ) + } + + enum JeAllocationKind { + Malloc, + MallocX( c_int ), + Calloc, + Aligned( size_t ) + } + + fn translate_jemalloc_flags( flags: c_int ) -> u32 { + const MALLOCX_ZERO: c_int = 0x40; + + let mut internal_flags = event::ALLOC_FLAG_JEMALLOC; + if flags & MALLOCX_ZERO != 0 { + internal_flags |= event::ALLOC_FLAG_CALLOC; + } + + internal_flags + } + + unsafe fn jemalloc_allocate( requested_size: usize, kind: JeAllocationKind ) -> *mut c_void { + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let mut thread = StrongThreadHandle::acquire(); + let (pointer, flags) = match kind { + JeAllocationKind::Malloc => (jem_malloc_real( effective_size ), event::ALLOC_FLAG_JEMALLOC), + JeAllocationKind::MallocX( flags ) => (jem_mallocx_real( effective_size, flags ), translate_jemalloc_flags( flags )), + JeAllocationKind::Calloc => (jem_calloc_real( 1, effective_size ), event::ALLOC_FLAG_JEMALLOC | event::ALLOC_FLAG_CALLOC), + JeAllocationKind::Aligned( alignment ) => (jem_memalign_real( alignment, effective_size as size_t ), event::ALLOC_FLAG_JEMALLOC), + }; + + if !crate::global::is_actively_running() { + thread = None; + } + + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return pointer + }; + + let usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( usable_size >= effective_size ); + let tracking_pointer = tracking_pointer( pointer, usable_size ); + + let mut thread = if let Some( thread ) = thread { + thread + } else { + std::ptr::write_unaligned( tracking_pointer, InternalAllocationId::UNTRACKED ); + return pointer; + }; + + let id = thread.on_new_allocation(); + std::ptr::write_unaligned( tracking_pointer, id ); + + let backtrace = unwind::grab( &mut thread ); let allocation = InternalAllocation { - address: new_address, + address, size: requested_size as usize, flags, tid: thread.system_tid(), extra_usable_space: 0, preceding_free_space: 0 }; - - on_reallocation( id, old_address, allocation, backtrace, thread ); - new_pointer - } else { - on_free( id, old_address, Some( backtrace ), thread ); - ptr::null_mut() - } -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_xallocx( pointer: *mut c_void, requested_size: size_t, extra: size_t, flags: c_int ) -> size_t { - let address = match NonZeroUsize::new( pointer as usize ) { - Some( address ) => address, - None => return 0 - }; - - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return _rjem_malloc_usable_size( pointer ) - }; - - let old_usable_size = jem_malloc_usable_size_real( pointer ); - let old_tracking_pointer = tracking_pointer( pointer, old_usable_size ); - let id = std::ptr::read_unaligned( old_tracking_pointer ); - debug_assert!( id.is_valid() ); - - let mut thread = StrongThreadHandle::acquire(); - let new_effective_size = jem_xallocx_real( pointer, effective_size, extra, flags ); - let new_requested_size = new_effective_size.checked_sub( mem::size_of::< InternalAllocationId >() ).expect( "_rjem_xallocx: underflow" ); - if id.is_untracked() && !crate::global::is_actively_running() { - thread = None; + + on_allocation( id, allocation, backtrace, thread ); + pointer + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_mallocx( requested_size: size_t, flags: c_int ) -> *mut c_void { + jemalloc_allocate( requested_size, JeAllocationKind::MallocX( flags ) ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_calloc( count: size_t, element_size: size_t ) -> *mut c_void { + let requested_size = match count.checked_mul( element_size ) { + None => return ptr::null_mut(), + Some( size ) => size + }; + + jemalloc_allocate( requested_size, JeAllocationKind::Calloc ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_sdallocx( pointer: *mut c_void, requested_size: size_t, flags: c_int ) { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return + }; + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return + }; + + let usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( usable_size >= effective_size, "tried to deallocate an allocation without space for the tracking pointer: 0x{:X}", pointer as usize ); + let tracking_pointer = tracking_pointer( pointer, usable_size ); + let id = std::ptr::read_unaligned( tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + jem_sdallocx_real( pointer, effective_size, flags ); + + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { thread } else { return }; + let backtrace = + if opt::get().grab_backtraces_on_free { + Some( unwind::grab( &mut thread ) ) + } else { + None + }; + + on_free( id, address, backtrace, thread ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_realloc( old_pointer: *mut c_void, requested_size: size_t ) -> *mut c_void { + jemalloc_reallocate( old_pointer, requested_size, None ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_rallocx( old_pointer: *mut c_void, requested_size: size_t, flags: c_int ) -> *mut c_void { + jemalloc_reallocate( old_pointer, requested_size, Some( flags ) ) + } + + unsafe fn jemalloc_reallocate( old_pointer: *mut c_void, requested_size: size_t, flags: Option< c_int > ) -> *mut c_void { + let old_address = match NonZeroUsize::new( old_pointer as usize ) { + Some( old_address ) => old_address, + None => return + if let Some( flags ) = flags { + _rjem_mallocx( requested_size, flags ) + } else { + _rjem_malloc( requested_size ) + } + }; + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return ptr::null_mut() + }; + + let old_usable_size = jem_malloc_usable_size_real( old_pointer ); + let old_tracking_pointer = tracking_pointer( old_pointer, old_usable_size ); + let id = std::ptr::read_unaligned( old_tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + let (new_pointer, flags) = if let Some( flags ) = flags { + (jem_rallocx_real( old_pointer, effective_size, flags ), translate_jemalloc_flags( flags )) + } else { + (jem_realloc_real( old_pointer, effective_size ), translate_jemalloc_flags( 0 )) + }; + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + if new_pointer.is_null() { + return ptr::null_mut(); + } else { + let new_usable_size = jem_malloc_usable_size_real( new_pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); + + return new_pointer; + } + }; + + let backtrace = unwind::grab( &mut thread ); + + if let Some( new_address ) = NonZeroUsize::new( new_pointer as usize ) { + let new_usable_size = jem_malloc_usable_size_real( new_pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( new_pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, id ); + + let allocation = InternalAllocation { + address: new_address, + size: requested_size as usize, + flags, + tid: thread.system_tid(), + extra_usable_space: 0, + preceding_free_space: 0 + }; + + on_reallocation( id, old_address, allocation, backtrace, thread ); + new_pointer + } else { + on_free( id, old_address, Some( backtrace ), thread ); + ptr::null_mut() + } } - - let mut thread = if let Some( thread ) = thread { - thread - } else { + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_xallocx( pointer: *mut c_void, requested_size: size_t, extra: size_t, flags: c_int ) -> size_t { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return 0 + }; + + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return _rjem_malloc_usable_size( pointer ) + }; + + let old_usable_size = jem_malloc_usable_size_real( pointer ); + let old_tracking_pointer = tracking_pointer( pointer, old_usable_size ); + let id = std::ptr::read_unaligned( old_tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + let new_effective_size = jem_xallocx_real( pointer, effective_size, extra, flags ); + let new_requested_size = new_effective_size.checked_sub( mem::size_of::< InternalAllocationId >() ).expect( "_rjem_xallocx: underflow" ); + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + let new_usable_size = jem_malloc_usable_size_real( pointer ); + debug_assert!( new_usable_size >= effective_size ); + let new_tracking_pointer = tracking_pointer( pointer, new_usable_size ); + std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); + + return new_requested_size; + }; + + let backtrace = unwind::grab( &mut thread ); + let new_usable_size = jem_malloc_usable_size_real( pointer ); debug_assert!( new_usable_size >= effective_size ); let new_tracking_pointer = tracking_pointer( pointer, new_usable_size ); - std::ptr::write_unaligned( new_tracking_pointer, InternalAllocationId::UNTRACKED ); - - return new_requested_size; - }; - - let backtrace = unwind::grab( &mut thread ); - - let new_usable_size = jem_malloc_usable_size_real( pointer ); - debug_assert!( new_usable_size >= effective_size ); - let new_tracking_pointer = tracking_pointer( pointer, new_usable_size ); - std::ptr::write_unaligned( new_tracking_pointer, id ); - - let allocation = InternalAllocation { - address: address, - size: new_requested_size as usize, - flags: translate_jemalloc_flags( flags ), - tid: thread.system_tid(), - extra_usable_space: 0, - preceding_free_space: 0 - }; - - on_reallocation( id, address, allocation, backtrace, thread ); - new_requested_size -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_nallocx( requested_size: size_t, flags: c_int ) -> size_t { - let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => size, - None => return 0 - }; - - jem_nallocx_real( effective_size, flags ).checked_sub( mem::size_of::< InternalAllocationId >() ).expect( "_rjem_nallocx: underflow" ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_malloc_usable_size( pointer: *mut c_void ) -> size_t { - let usable_size = jem_malloc_usable_size_real( pointer ); - match usable_size.checked_sub( mem::size_of::< InternalAllocationId >() ) { - Some( size ) => { - debug_assert!( std::ptr::read_unaligned( tracking_pointer( pointer, usable_size ) ).is_valid() ); - size - }, - None => panic!( "_rjem_malloc_usable_size: underflow (pointer=0x{:016X}, usable_size={})", pointer as usize , usable_size ) - } -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_mallctl( name: *const libc::c_char, _oldp: *mut c_void, _oldlenp: *mut size_t, _newp: *mut c_void, _newlen: size_t ) -> c_int { - warn!( "unimplemented: rjem_mallctl called: name={:?}", std::ffi::CStr::from_ptr( name ) ); - - 0 -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_posix_memalign( memptr: *mut *mut c_void, alignment: size_t, requested_size: size_t ) -> c_int { - if memptr.is_null() { - return libc::EINVAL; - } - - let ptr_size = mem::size_of::< *const c_void >(); - if alignment % ptr_size != 0 || !(alignment / ptr_size).is_power_of_two() || alignment == 0 { - return libc::EINVAL; - } - - let pointer = jemalloc_allocate( requested_size, JeAllocationKind::Aligned( alignment ) ); - *memptr = pointer; - - if pointer.is_null() { - libc::ENOMEM - } else { - 0 - } -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_aligned_alloc( _alignment: size_t, _size: size_t ) -> *mut c_void { - todo!( "_rjem_aligned_alloc" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_memalign( _alignment: size_t, _size: size_t ) -> *mut c_void { - todo!( "_rjem_memalign" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_valloc( _alignment: size_t, _size: size_t ) -> *mut c_void { - todo!( "_rjem_valloc" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_free( pointer: *mut c_void ) { - let address = match NonZeroUsize::new( pointer as usize ) { - Some( address ) => address, - None => return - }; - - let usable_size = jem_malloc_usable_size_real( pointer ); - let tracking_pointer = tracking_pointer( pointer, usable_size ); - let id = std::ptr::read_unaligned( tracking_pointer ); - debug_assert!( id.is_valid() ); - - let mut thread = StrongThreadHandle::acquire(); - jem_free_real( pointer ); - - if id.is_untracked() && !crate::global::is_actively_running() { - thread = None; - } - - let mut thread = if let Some( thread ) = thread { thread } else { return }; - let backtrace = if opt::get().grab_backtraces_on_free { - Some( unwind::grab( &mut thread ) ) - } else { - None - }; - - on_free( id, address, backtrace, thread ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_sallocx( _pointer: *const c_void, _flags: c_int ) -> size_t { - todo!( "_rjem_sallocx" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_dallocx( _pointer: *mut c_void, _flags: c_int ) { - todo!( "_rjem_dallocx" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_mallctlnametomib( name: *const libc::c_char, mibp: *mut size_t, miblenp: *mut size_t ) -> c_int { - jem_mallctlnametomib_real( name, mibp, miblenp ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_mallctlbymib( - mib: *const size_t, - miblen: size_t, - oldp: *mut c_void, - oldpenp: *mut size_t, - newp: *mut c_void, - newlen: size_t, -) -> c_int { - jem_mallctlbymib_real( mib, miblen, oldp, oldpenp, newp, newlen ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn _rjem_malloc_stats_print( - write_cb: Option< unsafe extern "C" fn( *mut c_void, *const libc::c_char ) >, - cbopaque: *mut c_void, - opts: *const libc::c_char, -) { - jem_malloc_stats_print_real( write_cb, cbopaque, opts ) -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn posix_memalign( memptr: *mut *mut c_void, alignment: size_t, requested_size: size_t ) -> c_int { - if memptr.is_null() { - return libc::EINVAL; + std::ptr::write_unaligned( new_tracking_pointer, id ); + + let allocation = InternalAllocation { + address: address, + size: new_requested_size as usize, + flags: translate_jemalloc_flags( flags ), + tid: thread.system_tid(), + extra_usable_space: 0, + preceding_free_space: 0 + }; + + on_reallocation( id, address, allocation, backtrace, thread ); + new_requested_size + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_nallocx( requested_size: size_t, flags: c_int ) -> size_t { + let effective_size = match requested_size.checked_add( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => size, + None => return 0 + }; + + jem_nallocx_real( effective_size, flags ).checked_sub( mem::size_of::< InternalAllocationId >() ).expect( "_rjem_nallocx: underflow" ) } - - let ptr_size = mem::size_of::< *const c_void >(); - if alignment % ptr_size != 0 || !(alignment / ptr_size).is_power_of_two() || alignment == 0 { - return libc::EINVAL; + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_malloc_usable_size( pointer: *mut c_void ) -> size_t { + let usable_size = jem_malloc_usable_size_real( pointer ); + match usable_size.checked_sub( mem::size_of::< InternalAllocationId >() ) { + Some( size ) => { + debug_assert!( std::ptr::read_unaligned( tracking_pointer( pointer, usable_size ) ).is_valid() ); + size + }, + None => panic!( "_rjem_malloc_usable_size: underflow (pointer=0x{:016X}, usable_size={})", pointer as usize , usable_size ) + } } - - let pointer = allocate( requested_size, AllocationKind::Aligned( alignment ) ); - *memptr = pointer; - - if pointer.is_null() { - libc::ENOMEM - } else { + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_mallctl( name: *const libc::c_char, _oldp: *mut c_void, _oldlenp: *mut size_t, _newp: *mut c_void, _newlen: size_t ) -> c_int { + warn!( "unimplemented: rjem_mallctl called: name={:?}", std::ffi::CStr::from_ptr( name ) ); + 0 } -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { - let mut thread = StrongThreadHandle::acquire(); - if !opt::get().gather_mmap_calls { - thread = None; - } - - let mut thread = if let Some( thread ) = thread { - thread - } else { - return syscall::mmap( addr, length, prot, flags, fildes, off ); - }; - - let backtrace = unwind::grab( &mut thread ); - - let _lock = crate::global::MMAP_LOCK.lock(); - let ptr = syscall::mmap( addr, length, prot, flags, fildes, off ); - - let timestamp = get_timestamp(); - send_event_throttled( || InternalEvent::Mmap { - pointer: ptr as usize, - length: length as usize, - requested_address: addr as usize, - mmap_protection: prot as u32, - mmap_flags: flags as u32, - file_descriptor: fildes as u32, - offset: off as u64, - backtrace, - timestamp, - thread: thread.decay() - }); - - ptr -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn munmap( ptr: *mut c_void, length: size_t ) -> c_int { - let mut thread = StrongThreadHandle::acquire(); - if !opt::get().gather_mmap_calls { - thread = None; - } - - let mut thread = if let Some( thread ) = thread { - thread - } else { - return syscall::munmap( ptr, length ); - }; - - let backtrace = unwind::grab( &mut thread ); - - let _lock = crate::global::MMAP_LOCK.lock(); - let result = syscall::munmap( ptr, length ); - - let timestamp = get_timestamp(); - send_event_throttled( || InternalEvent::Munmap { - ptr: ptr as usize, - len: length as usize, - backtrace, - timestamp, - thread: thread.decay() - }); - - result -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn mallopt( param: c_int, value: c_int ) -> c_int { - if crate::global::using_unprefixed_jemalloc() { - return 0; + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_posix_memalign( memptr: *mut *mut c_void, alignment: size_t, requested_size: size_t ) -> c_int { + if memptr.is_null() { + return libc::EINVAL; + } + + let ptr_size = mem::size_of::< *const c_void >(); + if alignment % ptr_size != 0 || !(alignment / ptr_size).is_power_of_two() || alignment == 0 { + return libc::EINVAL; + } + + let pointer = jemalloc_allocate( requested_size, JeAllocationKind::Aligned( alignment ) ); + *memptr = pointer; + + if pointer.is_null() { + libc::ENOMEM + } else { + 0 + } } - - let thread = StrongThreadHandle::acquire(); - let result = libc_mallopt_real( param, value ); - - let mut thread = if let Some( thread ) = thread { thread } else { return result }; - let backtrace = unwind::grab( &mut thread ); - - let timestamp = get_timestamp(); - send_event_throttled( || InternalEvent::Mallopt { - param: param as i32, - value: value as i32, - result: result as i32, - backtrace, - timestamp, - thread: thread.decay() - }); - - result -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn fork() -> libc::pid_t { - let pid = fork_real(); - if pid == 0 { - crate::global::on_fork(); - } else { - info!( "Fork called; child PID: {}", pid ); + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_aligned_alloc( _alignment: size_t, _size: size_t ) -> *mut c_void { + todo!( "_rjem_aligned_alloc" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_memalign( _alignment: size_t, _size: size_t ) -> *mut c_void { + todo!( "_rjem_memalign" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_valloc( _alignment: size_t, _size: size_t ) -> *mut c_void { + todo!( "_rjem_valloc" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_free( pointer: *mut c_void ) { + let address = match NonZeroUsize::new( pointer as usize ) { + Some( address ) => address, + None => return + }; + + let usable_size = jem_malloc_usable_size_real( pointer ); + let tracking_pointer = tracking_pointer( pointer, usable_size ); + let id = std::ptr::read_unaligned( tracking_pointer ); + debug_assert!( id.is_valid() ); + + let mut thread = StrongThreadHandle::acquire(); + jem_free_real( pointer ); + + if id.is_untracked() && !crate::global::is_actively_running() { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { thread } else { return }; + let backtrace = if opt::get().grab_backtraces_on_free { + Some( unwind::grab( &mut thread ) ) + } else { + None + }; + + on_free( id, address, backtrace, thread ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_sallocx( _pointer: *const c_void, _flags: c_int ) -> size_t { + todo!( "_rjem_sallocx" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_dallocx( _pointer: *mut c_void, _flags: c_int ) { + todo!( "_rjem_dallocx" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_mallctlnametomib( name: *const libc::c_char, mibp: *mut size_t, miblenp: *mut size_t ) -> c_int { + jem_mallctlnametomib_real( name, mibp, miblenp ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_mallctlbymib( + mib: *const size_t, + miblen: size_t, + oldp: *mut c_void, + oldpenp: *mut size_t, + newp: *mut c_void, + newlen: size_t, + ) -> c_int { + jem_mallctlbymib_real( mib, miblen, oldp, oldpenp, newp, newlen ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn _rjem_malloc_stats_print( + write_cb: Option< unsafe extern "C" fn( *mut c_void, *const libc::c_char ) >, + cbopaque: *mut c_void, + opts: *const libc::c_char, + ) { + jem_malloc_stats_print_real( write_cb, cbopaque, opts ) + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn posix_memalign( memptr: *mut *mut c_void, alignment: size_t, requested_size: size_t ) -> c_int { + if memptr.is_null() { + return libc::EINVAL; + } + + let ptr_size = mem::size_of::< *const c_void >(); + if alignment % ptr_size != 0 || !(alignment / ptr_size).is_power_of_two() || alignment == 0 { + return libc::EINVAL; + } + + let pointer = allocate( requested_size, AllocationKind::Aligned( alignment ) ); + *memptr = pointer; + + if pointer.is_null() { + libc::ENOMEM + } else { + 0 + } } - - pid -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn memalign( _alignment: size_t, _size: size_t ) -> *mut c_void { - unimplemented!( "'memalign' is unimplemented!" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn aligned_alloc( _alignment: size_t, _size: size_t ) -> *mut c_void { - unimplemented!( "'aligned_alloc' is unimplemented!" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn valloc( _size: size_t ) -> *mut c_void { - unimplemented!( "'valloc' is unimplemented!" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn pvalloc( _size: size_t ) -> *mut c_void { - unimplemented!( "'pvalloc' is unimplemented!" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn memory_profiler_set_marker( value: u32 ) { - let thread = StrongThreadHandle::acquire(); - send_event( InternalEvent::SetMarker { - value - }); - - mem::drop( thread ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn memory_profiler_override_next_timestamp( timestamp: u64 ) { - let thread = StrongThreadHandle::acquire(); - send_event_throttled( || InternalEvent::OverrideNextTimestamp { - timestamp: Timestamp::from_usecs( timestamp ) - }); - - mem::drop( thread ); -} - -fn sync() { - let thread = StrongThreadHandle::acquire(); - crate::event::flush(); - crate::global::sync(); - mem::drop( thread ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn memory_profiler_start() { - debug!( "Start called..." ); - if crate::global::enable() { - sync(); + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { + let mut thread = StrongThreadHandle::acquire(); + if !opt::get().gather_mmap_calls { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + return syscall::mmap( addr, length, prot, flags, fildes, off ); + }; + + let backtrace = unwind::grab( &mut thread ); + + let _lock = crate::global::MMAP_LOCK.lock(); + let ptr = syscall::mmap( addr, length, prot, flags, fildes, off ); + + let timestamp = get_timestamp(); + send_event_throttled( || InternalEvent::Mmap { + pointer: ptr as usize, + length: length as usize, + requested_address: addr as usize, + mmap_protection: prot as u32, + mmap_flags: flags as u32, + file_descriptor: fildes as u32, + offset: off as u64, + backtrace, + timestamp, + thread: thread.decay() + }); + + ptr + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn munmap( ptr: *mut c_void, length: size_t ) -> c_int { + let mut thread = StrongThreadHandle::acquire(); + if !opt::get().gather_mmap_calls { + thread = None; + } + + let mut thread = if let Some( thread ) = thread { + thread + } else { + return syscall::munmap( ptr, length ); + }; + + let backtrace = unwind::grab( &mut thread ); + + let _lock = crate::global::MMAP_LOCK.lock(); + let result = syscall::munmap( ptr, length ); + + let timestamp = get_timestamp(); + send_event_throttled( || InternalEvent::Munmap { + ptr: ptr as usize, + len: length as usize, + backtrace, + timestamp, + thread: thread.decay() + }); + + result + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn mallopt( param: c_int, value: c_int ) -> c_int { + if crate::global::using_unprefixed_jemalloc() { + return 0; + } + + let thread = StrongThreadHandle::acquire(); + let result = libc_mallopt_real( param, value ); + + let mut thread = if let Some( thread ) = thread { thread } else { return result }; + let backtrace = unwind::grab( &mut thread ); + + let timestamp = get_timestamp(); + send_event_throttled( || InternalEvent::Mallopt { + param: param as i32, + value: value as i32, + result: result as i32, + backtrace, + timestamp, + thread: thread.decay() + }); + + result + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn fork() -> libc::pid_t { + let pid = fork_real(); + if pid == 0 { + crate::global::on_fork(); + } else { + info!( "Fork called; child PID: {}", pid ); + } + + pid + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn memalign( _alignment: size_t, _size: size_t ) -> *mut c_void { + unimplemented!( "'memalign' is unimplemented!" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn aligned_alloc( _alignment: size_t, _size: size_t ) -> *mut c_void { + unimplemented!( "'aligned_alloc' is unimplemented!" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn valloc( _size: size_t ) -> *mut c_void { + unimplemented!( "'valloc' is unimplemented!" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn pvalloc( _size: size_t ) -> *mut c_void { + unimplemented!( "'pvalloc' is unimplemented!" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn memory_profiler_set_marker( value: u32 ) { + let thread = StrongThreadHandle::acquire(); + send_event( InternalEvent::SetMarker { + value + }); + + mem::drop( thread ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn memory_profiler_override_next_timestamp( timestamp: u64 ) { + let thread = StrongThreadHandle::acquire(); + send_event_throttled( || InternalEvent::OverrideNextTimestamp { + timestamp: Timestamp::from_usecs( timestamp ) + }); + + mem::drop( thread ); + } + + fn sync() { + let thread = StrongThreadHandle::acquire(); + crate::event::flush(); + crate::global::sync(); + mem::drop( thread ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn memory_profiler_start() { + debug!( "Start called..." ); + if crate::global::enable() { + sync(); + } + debug!( "Start finished" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn memory_profiler_stop() { + debug!( "Stop called..." ); + if crate::global::disable() { + sync(); + } + debug!( "Stop finished" ); } - debug!( "Start finished" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn memory_profiler_stop() { - debug!( "Stop called..." ); - if crate::global::disable() { + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn memory_profiler_sync() { + debug!( "Sync called..." ); sync(); + debug!( "Sync finished" ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn __register_frame( fde: *const u8 ) { + debug!( "Registering new frame: 0x{:016X}", fde as usize ); + + if let Some( original ) = crate::global::SYM_REGISTER_FRAME { + original( fde ) + } else { + error!( "__register_frame call ignored since we couldn't find the original symbol" ); + } + + let thread = StrongThreadHandle::acquire(); + unwind::register_frame_by_pointer( fde ); + std::mem::drop( thread ); + } + + #[cfg_attr(not(test), no_mangle)] + pub unsafe extern "C" fn __deregister_frame( fde: *const u8 ) { + debug!( "Deregistering new frame: 0x{:016X}", fde as usize ); + + if let Some( original ) = crate::global::SYM_DEREGISTER_FRAME { + original( fde ) + } else { + error!( "__deregister_frame call ignored since we couldn't find the original symbol" ); + } + + let thread = StrongThreadHandle::acquire(); + unwind::deregister_frame_by_pointer( fde ); + std::mem::drop( thread ); } - debug!( "Stop finished" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn memory_profiler_sync() { - debug!( "Sync called..." ); - sync(); - debug!( "Sync finished" ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn __register_frame( fde: *const u8 ) { - debug!( "Registering new frame: 0x{:016X}", fde as usize ); - - if let Some( original ) = crate::global::SYM_REGISTER_FRAME { - original( fde ) - } else { - error!( "__register_frame call ignored since we couldn't find the original symbol" ); - } - - let thread = StrongThreadHandle::acquire(); - unwind::register_frame_by_pointer( fde ); - std::mem::drop( thread ); -} - -#[cfg_attr(not(test), no_mangle)] -pub unsafe extern "C" fn __deregister_frame( fde: *const u8 ) { - debug!( "Deregistering new frame: 0x{:016X}", fde as usize ); - - if let Some( original ) = crate::global::SYM_DEREGISTER_FRAME { - original( fde ) - } else { - error!( "__deregister_frame call ignored since we couldn't find the original symbol" ); - } - - let thread = StrongThreadHandle::acquire(); - unwind::deregister_frame_by_pointer( fde ); - std::mem::drop( thread ); -} + \ No newline at end of file diff --git a/preload-syscallee/src/lib.rs b/preload-syscallee/src/lib.rs index 6565759b..c463d897 100644 --- a/preload-syscallee/src/lib.rs +++ b/preload-syscallee/src/lib.rs @@ -61,35 +61,35 @@ lazy_static! { }; } -//pub use crate::api::{ -// memory_profiler_raw_mmap, -// memory_profiler_raw_munmap, -// -// __register_frame, -// __deregister_frame, -// -// _exit, -// _Exit, -// fork, -// -// malloc, -// calloc, -// realloc, -// reallocarray, -// free, -// posix_memalign, -// malloc_usable_size, -// mmap, -// munmap, -// mallopt, -// memalign, -// aligned_alloc, -// valloc, -// pvalloc, -// -// memory_profiler_set_marker, -// memory_profiler_override_next_timestamp, -// memory_profiler_start, -// memory_profiler_stop, -// memory_profiler_sync -//}; +pub use crate::api::{ + memory_profiler_raw_mmap, + memory_profiler_raw_munmap, + + __register_frame, + __deregister_frame, + + _exit, + _Exit, + fork, + + malloc, + calloc, + realloc, + reallocarray, + free, + posix_memalign, + malloc_usable_size, + mmap, + munmap, + mallopt, + memalign, + aligned_alloc, + valloc, + pvalloc, + + memory_profiler_set_marker, + memory_profiler_override_next_timestamp, + memory_profiler_start, + memory_profiler_stop, + memory_profiler_sync +}; diff --git a/preload-syscaller/src/api.rs b/preload-syscaller/src/api.rs index bc124375..4989642a 100644 --- a/preload-syscaller/src/api.rs +++ b/preload-syscaller/src/api.rs @@ -72,13 +72,13 @@ extern "C" { fn fork_real() -> libc::pid_t; } -pub unsafe extern "C" fn memory_profiler_raw_mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { - syscall::mmap( addr, length, prot, flags, fildes, off ) -} +//pub unsafe extern "C" fn memory_profiler_raw_mmap( addr: *mut c_void, length: size_t, prot: c_int, flags: c_int, fildes: c_int, off: off_t ) -> *mut c_void { +// syscall::mmap( addr, length, prot, flags, fildes, off ) +//} -pub unsafe extern "C" fn memory_profiler_raw_munmap( addr: *mut c_void, length: size_t ) -> c_int { - syscall::munmap( addr, length ) -} +//pub unsafe extern "C" fn memory_profiler_raw_munmap( addr: *mut c_void, length: size_t ) -> c_int { +// syscall::munmap( addr, length ) +//} pub unsafe extern "C" fn _exit( status: c_int ) { on_exit(); diff --git a/preload-syscaller/src/lib.rs b/preload-syscaller/src/lib.rs index 11914223..c8cf02e9 100644 --- a/preload-syscaller/src/lib.rs +++ b/preload-syscaller/src/lib.rs @@ -62,9 +62,6 @@ lazy_static! { } pub use crate::api::{ - memory_profiler_raw_mmap, - memory_profiler_raw_munmap, - __register_frame, __deregister_frame,