auto merge of #14715 : vhbit/rust/ios-pr2, r=alexcrichton
This commit is contained in:
commit
2ef910f71a
@ -155,36 +155,76 @@ CFG_LDPATH_i686-unknown-linux-gnu :=
|
||||
CFG_RUN_i686-unknown-linux-gnu=$(2)
|
||||
CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))
|
||||
|
||||
# arm-apple-darwin configuration
|
||||
ifeq ($(CFG_OSTYPE),apple-darwin)
|
||||
# arm-apple-ios configuration
|
||||
CFG_SDK_NAME_arm-apple-ios = iphoneos
|
||||
CFG_SDK_ARCHS_arm-apple-ios = armv7
|
||||
ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
|
||||
CFG_IOS_SDK = $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
|
||||
CFG_IOS_FLAGS = -target arm-apple-darwin -isysroot $(CFG_IOS_SDK) -I$(CFG_IOS_SDK)/usr/include -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
|
||||
CC_arm-apple-darwin = $(shell xcrun -find -sdk iphoneos clang)
|
||||
CXX_arm-apple-darwin = $(shell xcrun -find -sdk iphoneos clang++)
|
||||
CPP_arm-apple-darwin = $(shell xcrun -find -sdk iphoneos clang++)
|
||||
AR_arm-apple-darwin = $(shell xcrun -find -sdk iphoneos ar)
|
||||
CFG_LIB_NAME_arm-apple-darwin = lib$(1).dylib
|
||||
CFG_LIB_GLOB_arm-apple-darwin = lib$(1)-*.dylib
|
||||
CFG_LIB_DSYM_GLOB_arm-apple-darwin = lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_arm-apple-darwin := $(CFG_IOS_FLAGS) $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_arm-apple-darwin := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_arm-apple-darwin := -fno-rtti $(CFG_IOS_FLAGS) $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_arm-apple-darwin := -dynamiclib -lpthread -framework CoreServices -Wl,-no_compact_unwind
|
||||
CFG_GCCISH_DEF_FLAG_arm-apple-darwin := -Wl,-exported_symbols_list,
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-darwin :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-darwin :=
|
||||
CFG_DEF_SUFFIX_arm-apple-darwin := .darwin.def
|
||||
CFG_LLC_FLAGS_arm-apple-darwin :=
|
||||
CFG_INSTALL_NAME_arm-apple-darwin = -Wl,-install_name,@rpath/$(1)
|
||||
CFG_LIBUV_LINK_FLAGS_arm-apple-darwin =
|
||||
CFG_EXE_SUFFIX_arm-apple-darwin :=
|
||||
CFG_WINDOWSY_arm-apple-darwin :=
|
||||
CFG_UNIXY_arm-apple-darwin := 1
|
||||
CFG_PATH_MUNGE_arm-apple-darwin := true
|
||||
CFG_LDPATH_arm-apple-darwin :=
|
||||
CFG_RUN_arm-apple-darwin = $(2)
|
||||
CFG_RUN_TARG_arm-apple-darwin = $(call CFG_RUN_arm-apple-darwin,,$(2))
|
||||
CFG_IOS_FLAGS = -target armv7-apple-darwin -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
|
||||
CC_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
|
||||
CXX_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
|
||||
CPP_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
|
||||
AR_arm-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
|
||||
endif
|
||||
CFG_LIB_NAME_arm-apple-ios = lib$(1).a
|
||||
CFG_LIB_GLOB_arm-apple-ios = lib$(1)-*.a
|
||||
CFG_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
|
||||
CFG_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
|
||||
CFG_GCCISH_CFLAGS_arm-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) -mfpu=vfp3 -arch armv7
|
||||
CFG_GCCISH_CXXFLAGS_arm-apple-ios := -fno-rtti $(CFG_IOS_FLAGS) -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_arm-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK) -Wl,-no_compact_unwind
|
||||
CFG_GCCISH_DEF_FLAG_arm-apple-ios := -Wl,-exported_symbols_list,
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-ios :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-ios :=
|
||||
CFG_DEF_SUFFIX_arm-apple-ios := .darwin.def
|
||||
CFG_LLC_FLAGS_arm-apple-ios := -mattr=+vfp3,+v7,+thumb2,+neon -march=arm
|
||||
CFG_INSTALL_NAME_arm-apple-ios = -Wl,-install_name,@rpath/$(1)
|
||||
CFG_LIBUV_LINK_FLAGS_arm-apple-ios =
|
||||
CFG_EXE_SUFFIX_arm-apple-ios :=
|
||||
CFG_WINDOWSY_arm-apple-ios :=
|
||||
CFG_UNIXY_arm-apple-ios := 1
|
||||
CFG_PATH_MUNGE_arm-apple-ios := true
|
||||
CFG_LDPATH_arm-apple-ios :=
|
||||
CFG_RUN_arm-apple-ios = $(2)
|
||||
CFG_RUN_TARG_arm-apple-ios = $(call CFG_RUN_arm-apple-ios,,$(2))
|
||||
RUSTC_FLAGS_arm-apple-ios := -C relocation_model=pic
|
||||
RUSTC_CROSS_FLAGS_arm-apple-ios :=-C relocation_model=pic
|
||||
|
||||
# i386-apple-ios configuration
|
||||
CFG_SDK_NAME_i386-apple-ios = iphonesimulator
|
||||
CFG_SDK_ARCHS_i386-apple-ios = i386
|
||||
ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
|
||||
CFG_IOSSIM_SDK = $(shell xcrun --show-sdk-path -sdk iphonesimulator 2>/dev/null)
|
||||
CFG_IOSSIM_FLAGS = -target i386-apple-ios -isysroot $(CFG_IOSSIM_SDK) -mios-simulator-version-min=7.0
|
||||
CC_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang)
|
||||
CXX_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
|
||||
CPP_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
|
||||
AR_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator ar)
|
||||
endif
|
||||
CFG_LIB_NAME_i386-apple-ios = lib$(1).a
|
||||
CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
|
||||
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
|
||||
CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS)
|
||||
CFG_GCCISH_CFLAGS_i386-apple-ios = -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_i386-apple-ios = -fno-rtti $(CFG_IOSSIM_FLAGS) -I$(CFG_IOSSIM_SDK)/usr/include/c++/4.2.1
|
||||
CFG_GCCISH_LINK_FLAGS_i386-apple-ios = -lpthread -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK)
|
||||
CFG_GCCISH_DEF_FLAG_i386-apple-ios = -Wl,-exported_symbols_list,
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios =
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios =
|
||||
CFG_DEF_SUFFIX_i386-apple-ios = .darwin.def
|
||||
CFG_LLC_FLAGS_i386-apple-ios =
|
||||
CFG_INSTALL_NAME_i386-apple-ios = -Wl,-install_name,@rpath/$(1)
|
||||
CFG_LIBUV_LINK_FLAGS_i386-apple-ios =
|
||||
CFG_EXE_SUFFIX_i386-apple-ios =
|
||||
CFG_WINDOWSY_i386-apple-ios =
|
||||
CFG_UNIXY_i386-apple-ios = 1
|
||||
CFG_PATH_MUNGE_i386-apple-ios = true
|
||||
CFG_LDPATH_i386-apple-ios =
|
||||
CFG_RUN_i386-apple-ios = $(2)
|
||||
CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
|
||||
CFG_JEMALLOC_CFLAGS_i386-apple-ios = -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
|
||||
|
||||
# x86_64-apple-darwin configuration
|
||||
CC_x86_64-apple-darwin=$(CC)
|
||||
|
48
mk/rt.mk
48
mk/rt.mk
@ -166,6 +166,9 @@ ifeq ($$(CFG_WINDOWSY_$(1)), 1)
|
||||
JEMALLOC_ARGS_$(1) := --enable-lazy-lock
|
||||
else ifeq ($(OSTYPE_$(1)), apple-darwin)
|
||||
LIBUV_OSTYPE_$(1) := mac
|
||||
else ifeq ($(OSTYPE_$(1)), apple-ios)
|
||||
LIBUV_OSTYPE_$(1) := ios
|
||||
JEMALLOC_ARGS_$(1) := --disable-tls
|
||||
else ifeq ($(OSTYPE_$(1)), unknown-freebsd)
|
||||
LIBUV_OSTYPE_$(1) := freebsd
|
||||
else ifeq ($(OSTYPE_$(1)), linux-androideabi)
|
||||
@ -181,6 +184,8 @@ LIBUV_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/libuv
|
||||
LIBUV_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(LIBUV_NAME_$(1))
|
||||
|
||||
LIBUV_MAKEFILE_$(1) := $$(CFG_BUILD_DIR)$$(RT_OUTPUT_DIR_$(1))/libuv/Makefile
|
||||
LIBUV_BUILD_DIR_$(1) := $$(CFG_BUILD_DIR)$$(RT_OUTPUT_DIR_$(1))/libuv
|
||||
LIBUV_XCODEPROJ_$(1) := $$(LIBUV_BUILD_DIR_$(1))/uv.xcodeproj
|
||||
|
||||
LIBUV_STAMP_$(1) = $$(LIBUV_DIR_$(1))/libuv-auto-clean-stamp
|
||||
|
||||
@ -212,6 +217,30 @@ $$(LIBUV_LOCAL_$(1)): $$(LIBUV_DEPS) $$(MKFILE_DEPS)
|
||||
CXX="$$(CXX_$(1))" \
|
||||
AR="$$(AR_$(1))" \
|
||||
V=$$(VERBOSE)
|
||||
else ifeq ($(OSTYPE_$(1)), apple-ios) # iOS
|
||||
$$(LIBUV_XCODEPROJ_$(1)): $$(LIBUV_DEPS) $$(MKFILE_DEPS) $$(LIBUV_STAMP_$(1))
|
||||
cp -rf $(S)src/libuv/ $$(LIBUV_BUILD_DIR_$(1))
|
||||
(cd $$(LIBUV_BUILD_DIR_$(1)) && \
|
||||
$$(CFG_PYTHON) ./gyp_uv.py -f xcode \
|
||||
-D ninja \
|
||||
-R libuv)
|
||||
touch $$@
|
||||
|
||||
LIBUV_XCODE_OUT_LIB_$(1) := $$(LIBUV_BUILD_DIR_$(1))/build/Release-$$(CFG_SDK_NAME_$(1))/libuv.a
|
||||
|
||||
$$(LIBUV_LIB_$(1)): $$(LIBUV_XCODE_OUT_LIB_$(1)) $$(MKFILE_DEPS)
|
||||
$$(Q)cp $$< $$@
|
||||
$$(LIBUV_XCODE_OUT_LIB_$(1)): $$(LIBUV_DEPS) $$(LIBUV_XCODEPROJ_$(1)) \
|
||||
$$(MKFILE_DEPS)
|
||||
$$(Q)xcodebuild -project $$(LIBUV_BUILD_DIR_$(1))/uv.xcodeproj \
|
||||
CFLAGS="$$(LIBUV_CFLAGS_$(1)) $$(SNAP_DEFINES)" \
|
||||
LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS_$(1))" \
|
||||
$$(LIBUV_ARGS_$(1)) \
|
||||
V=$$(VERBOSE) \
|
||||
-configuration Release \
|
||||
-sdk "$$(CFG_SDK_NAME_$(1))" \
|
||||
ARCHS="$$(CFG_SDK_ARCHS_$(1))"
|
||||
$$(Q)touch $$@
|
||||
else
|
||||
LIBUV_LOCAL_$(1) := $$(LIBUV_DIR_$(1))/Release/libuv.a
|
||||
$$(LIBUV_LOCAL_$(1)): $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)) $$(MKFILE_DEPS)
|
||||
@ -226,7 +255,6 @@ $$(LIBUV_LOCAL_$(1)): $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)) $$(MKFILE_DEPS)
|
||||
NO_LOAD="$$(LIBUV_NO_LOAD)" \
|
||||
V=$$(VERBOSE)
|
||||
$$(Q)touch $$@
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(1),$$(CFG_BUILD))
|
||||
@ -269,13 +297,13 @@ JEMALLOC_LOCAL_$(1) := $$(JEMALLOC_BUILD_DIR_$(1))/lib/$$(JEMALLOC_REAL_NAME_$(1
|
||||
$$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
|
||||
@$$(call E, make: jemalloc)
|
||||
cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
|
||||
$$(JEMALLOC_ARGS_$(1)) --enable-cc-silence --with-jemalloc-prefix=je_ \
|
||||
--disable-experimental --build=$(CFG_BUILD) --host=$(1) \
|
||||
$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ \
|
||||
--build=$(CFG_BUILD) --host=$(1) \
|
||||
CC="$$(CC_$(1))" \
|
||||
AR="$$(AR_$(1))" \
|
||||
RANLIB="$$(AR_$(1)) s" \
|
||||
CPPFLAGS="-I $(S)src/rt/" \
|
||||
EXTRA_CFLAGS="$$(CFG_CFLAGS_$(1)) -g1"
|
||||
EXTRA_CFLAGS="$$(CFG_CFLAGS_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1)) -g1"
|
||||
$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
|
||||
|
||||
ifeq ($(1),$$(CFG_BUILD))
|
||||
@ -335,15 +363,22 @@ BACKTRACE_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),backtrace)
|
||||
BACKTRACE_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(BACKTRACE_NAME_$(1))
|
||||
BACKTRACE_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/libbacktrace
|
||||
|
||||
ifeq ($$(findstring darwin,$$(OSTYPE_$(1))),darwin)
|
||||
|
||||
# We don't use this on platforms that aren't linux-based, so just make the file
|
||||
# available, the compilation of libstd won't actually build it.
|
||||
ifeq ($$(findstring darwin,$$(OSTYPE_$(1))),darwin)
|
||||
# See comment above
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
|
||||
else
|
||||
ifeq ($$(findstring ios,$$(OSTYPE_$(1))),ios)
|
||||
# See comment above
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
else
|
||||
|
||||
ifeq ($$(CFG_WINDOWSY_$(1)),1)
|
||||
# See comment above
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
else
|
||||
@ -388,6 +423,7 @@ $$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_BUILD_DIR_$(1))/Makefile $$(MKFILE_DEPS)
|
||||
$$(Q)cp $$(BACKTRACE_BUILD_DIR_$(1))/.libs/libbacktrace.a $$@
|
||||
|
||||
endif # endif for windowsy
|
||||
endif # endif for ios
|
||||
endif # endif for darwin
|
||||
|
||||
endef
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit ed112ca1e4275e1c5707a898f2bf6164707ba378
|
||||
Subproject commit 7b97b8468f0614072cf3299fa8c51e85f609316f
|
@ -1 +1 @@
|
||||
Subproject commit 6a96910f2eaea6d2c705bb12379b23576b30d7d5
|
||||
Subproject commit 024c67ad651e1a3ca228936c4cfb13a37329baf2
|
@ -278,10 +278,13 @@ pub use consts::os::extra::{MAP_STACK};
|
||||
pub use consts::os::bsd44::{TCP_KEEPIDLE};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub use consts::os::bsd44::{TCP_KEEPALIVE};
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub use consts::os::extra::{F_FULLFSYNC};
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub use types::os::arch::extra::{mach_timebase_info};
|
||||
|
||||
|
||||
@ -1286,6 +1289,7 @@ pub mod types {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub mod os {
|
||||
pub mod common {
|
||||
pub mod posix01 {
|
||||
@ -3106,6 +3110,7 @@ pub mod consts {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub mod os {
|
||||
pub mod c95 {
|
||||
use types::os::arch::c95::{c_int, c_uint};
|
||||
@ -3769,6 +3774,7 @@ pub mod funcs {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod posix88 {
|
||||
pub mod stat_ {
|
||||
@ -3783,6 +3789,7 @@ pub mod funcs {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@ -3795,6 +3802,7 @@ pub mod funcs {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub fn stat(path: *c_char, buf: *mut stat) -> c_int;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@ -3967,6 +3975,7 @@ pub mod funcs {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod posix01 {
|
||||
pub mod stat_ {
|
||||
@ -3977,6 +3986,7 @@ pub mod funcs {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub fn lstat(path: *c_char, buf: *mut stat) -> c_int;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@ -4076,6 +4086,7 @@ pub mod funcs {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod posix08 {
|
||||
pub mod unistd {
|
||||
@ -4156,6 +4167,7 @@ pub mod funcs {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod bsd44 {
|
||||
use types::common::c95::{c_void};
|
||||
@ -4209,6 +4221,7 @@ pub mod funcs {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub mod extra {
|
||||
use types::os::arch::c95::{c_char, c_int};
|
||||
|
||||
|
@ -20,6 +20,7 @@ pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};
|
||||
use libc;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub static FIONBIO: libc::c_ulong = 0x8004667e;
|
||||
#[cfg(target_os = "linux", not(target_arch = "mips"))]
|
||||
@ -29,6 +30,7 @@ pub static FIONBIO: libc::c_ulong = 0x5421;
|
||||
pub static FIONBIO: libc::c_ulong = 0x667e;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub static FIOCLEX: libc::c_ulong = 0x20006601;
|
||||
#[cfg(target_os = "linux", not(target_arch = "mips"))]
|
||||
@ -38,6 +40,7 @@ pub static FIOCLEX: libc::c_ulong = 0x5451;
|
||||
pub static FIOCLEX: libc::c_ulong = 0x6601;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub static MSG_DONTWAIT: libc::c_int = 0x80;
|
||||
#[cfg(target_os = "linux")]
|
||||
@ -75,6 +78,7 @@ extern {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
mod select {
|
||||
pub static FD_SETSIZE: uint = 1024;
|
||||
|
||||
@ -187,6 +191,7 @@ mod signal {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
mod signal {
|
||||
use libc;
|
||||
@ -201,6 +206,7 @@ mod signal {
|
||||
pub static SIGCHLD: libc::c_int = 20;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub type sigset_t = u32;
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub struct sigset_t {
|
||||
@ -219,6 +225,7 @@ mod signal {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
pub struct sigaction {
|
||||
pub sa_handler: extern fn(libc::c_int),
|
||||
sa_tramp: *mut libc::c_void,
|
||||
|
@ -133,6 +133,7 @@ impl rtio::RtioFileStream for FileDesc {
|
||||
return super::mkerr_libc(os_datasync(self.fd()));
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
fn os_datasync(fd: c_int) -> c_int {
|
||||
unsafe { libc::fcntl(fd, libc::F_FULLFSYNC) }
|
||||
}
|
||||
@ -140,7 +141,7 @@ impl rtio::RtioFileStream for FileDesc {
|
||||
fn os_datasync(fd: c_int) -> c_int {
|
||||
retry(|| unsafe { libc::fdatasync(fd) })
|
||||
}
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "linux"))]
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "linux"))]
|
||||
fn os_datasync(fd: c_int) -> c_int {
|
||||
retry(|| unsafe { libc::fsync(fd) })
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ pub mod file;
|
||||
pub mod file;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -320,6 +320,7 @@ impl TcpStream {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
|
||||
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
|
||||
seconds as libc::c_int)
|
||||
@ -329,7 +330,7 @@ impl TcpStream {
|
||||
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
|
||||
seconds as libc::c_int)
|
||||
}
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "freebsd"))]
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "freebsd"))]
|
||||
fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -769,6 +769,7 @@ fn translate_status(status: c_int) -> rtio::ProcessExit {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
mod imp {
|
||||
pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
|
||||
|
@ -93,7 +93,20 @@ pub fn now() -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
|
||||
|
||||
// Note: although the last parameter isn't used there is no way now to
|
||||
// convert it to unit type, because LLVM dies in SjLj preparation
|
||||
// step (unfortunately iOS uses SjLJ exceptions)
|
||||
//
|
||||
// It's definitely a temporary workaround just to get it working.
|
||||
// So far it looks like an LLVM issue and it was reported:
|
||||
// http://llvm.org/bugs/show_bug.cgi?id=19855
|
||||
// Actually this issue is pretty common while compiling for armv7 iOS
|
||||
// and in most cases it is simply solved by using --opt-level=2 (or -O)
|
||||
//
|
||||
// For this specific case unfortunately turning optimizations wasn't
|
||||
// enough.
|
||||
fn helper(input: libc::c_int, messages: Receiver<Req>, _: int) {
|
||||
let mut set: c::fd_set = unsafe { mem::zeroed() };
|
||||
|
||||
let mut fd = FileDesc::new(input, true);
|
||||
@ -202,7 +215,9 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
|
||||
|
||||
impl Timer {
|
||||
pub fn new() -> IoResult<Timer> {
|
||||
unsafe { HELPER.boot(|| {}, helper); }
|
||||
// See notes above regarding using int return value
|
||||
// instead of ()
|
||||
unsafe { HELPER.boot(|| {0}, helper); }
|
||||
|
||||
static mut ID: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
|
||||
let id = unsafe { ID.fetch_add(1, atomics::Relaxed) };
|
||||
|
@ -9,8 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
use back::target_strs;
|
||||
use driver::config::cfg_os_to_meta_os;
|
||||
use metadata::loader::meta_section_name;
|
||||
use syntax::abi;
|
||||
|
||||
pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
|
||||
@ -22,9 +20,6 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
|
||||
return target_strs::t {
|
||||
module_asm: "".to_string(),
|
||||
|
||||
meta_sect_name:
|
||||
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
|
||||
|
||||
data_layout: match target_os {
|
||||
abi::OsMacos => {
|
||||
"e-p:32:32:32\
|
||||
@ -34,6 +29,14 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
|
||||
-a0:0:64-n32".to_string()
|
||||
}
|
||||
|
||||
abi::OsiOS => {
|
||||
"e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string()
|
||||
}
|
||||
|
||||
abi::OsWin32 => {
|
||||
"e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
|
@ -114,6 +114,13 @@ pub mod write {
|
||||
// which are *far* more efficient. This is obviously undesirable in some
|
||||
// cases, so if any sort of target feature is specified we don't append v7
|
||||
// to the feature list.
|
||||
//
|
||||
// On iOS only armv7 and newer are supported. So it is useful to
|
||||
// get all hardware potential via VFP3 (hardware floating point)
|
||||
// and NEON (SIMD) instructions supported by LLVM.
|
||||
// Note that without those flags various linking errors might
|
||||
// arise as some of intrinsicts are converted into function calls
|
||||
// and nobody provides implementations those functions
|
||||
fn target_feature<'a>(sess: &'a Session) -> &'a str {
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsAndroid => {
|
||||
@ -122,7 +129,10 @@ pub mod write {
|
||||
} else {
|
||||
sess.opts.cg.target_feature.as_slice()
|
||||
}
|
||||
}
|
||||
},
|
||||
abi::OsiOS if sess.targ_cfg.arch == abi::Arm => {
|
||||
"+v7,+thumb2,+vfp3,+neon"
|
||||
},
|
||||
_ => sess.opts.cg.target_feature.as_slice()
|
||||
}
|
||||
}
|
||||
@ -796,6 +806,10 @@ pub fn link_binary(sess: &Session,
|
||||
id: &CrateId) -> Vec<Path> {
|
||||
let mut out_filenames = Vec::new();
|
||||
for &crate_type in sess.crate_types.borrow().iter() {
|
||||
if invalid_output_for_target(sess, crate_type) {
|
||||
sess.bug(format!("invalid output type `{}` for target os `{}`",
|
||||
crate_type, sess.targ_cfg.os).as_slice());
|
||||
}
|
||||
let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
|
||||
out_filenames.push(out_file);
|
||||
}
|
||||
@ -812,6 +826,32 @@ pub fn link_binary(sess: &Session,
|
||||
out_filenames
|
||||
}
|
||||
|
||||
|
||||
/// Returns default crate type for target
|
||||
///
|
||||
/// Default crate type is used when crate type isn't provided neither
|
||||
/// through cmd line arguments nor through crate attributes
|
||||
///
|
||||
/// It is CrateTypeExecutable for all platforms but iOS as there is no
|
||||
/// way to run iOS binaries anyway without jailbreaking and
|
||||
/// interaction with Rust code through static library is the only
|
||||
/// option for now
|
||||
pub fn default_output_for_target(sess: &Session) -> config::CrateType {
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsiOS => config::CrateTypeStaticlib,
|
||||
_ => config::CrateTypeExecutable
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if target supports crate_type as output
|
||||
pub fn invalid_output_for_target(sess: &Session,
|
||||
crate_type: config::CrateType) -> bool {
|
||||
match (sess.targ_cfg.os, crate_type) {
|
||||
(abi::OsiOS, config::CrateTypeDylib) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_writeable(p: &Path) -> bool {
|
||||
match p.stat() {
|
||||
Err(..) => true,
|
||||
@ -833,8 +873,11 @@ pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
|
||||
abi::OsLinux => (loader::LINUX_DLL_PREFIX, loader::LINUX_DLL_SUFFIX),
|
||||
abi::OsAndroid => (loader::ANDROID_DLL_PREFIX, loader::ANDROID_DLL_SUFFIX),
|
||||
abi::OsFreebsd => (loader::FREEBSD_DLL_PREFIX, loader::FREEBSD_DLL_SUFFIX),
|
||||
abi::OsiOS => unreachable!(),
|
||||
};
|
||||
out_filename.with_filename(format!("{}{}{}", prefix, libname,
|
||||
out_filename.with_filename(format!("{}{}{}",
|
||||
prefix,
|
||||
libname,
|
||||
suffix))
|
||||
}
|
||||
config::CrateTypeStaticlib => {
|
||||
@ -991,7 +1034,7 @@ fn link_rlib<'a>(sess: &'a Session,
|
||||
// symbol table of the archive. This currently dies on OSX (see
|
||||
// #11162), and isn't necessary there anyway
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsMacos => {}
|
||||
abi::OsMacos | abi::OsiOS => {}
|
||||
_ => { a.update_symbols(); }
|
||||
}
|
||||
}
|
||||
@ -1104,15 +1147,16 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
|
||||
|
||||
// On OSX, debuggers need this utility to get run to do some munging of
|
||||
// the symbols
|
||||
if sess.targ_cfg.os == abi::OsMacos && (sess.opts.debuginfo != NoDebugInfo) {
|
||||
match Command::new("dsymutil").arg(out_filename).status() {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to run dsymutil: {}", e).as_slice());
|
||||
sess.abort_if_errors();
|
||||
if (sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS)
|
||||
&& (sess.opts.debuginfo != NoDebugInfo) {
|
||||
match Command::new("dsymutil").arg(out_filename).status() {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to run dsymutil: {}", e).as_slice());
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn link_args(cmd: &mut Command,
|
||||
@ -1169,7 +1213,7 @@ fn link_args(cmd: &mut Command,
|
||||
// already done the best it can do, and we also don't want to eliminate the
|
||||
// metadata. If we're building an executable, however, --gc-sections drops
|
||||
// the size of hello world from 1.8MB to 597K, a 67% reduction.
|
||||
if !dylib && sess.targ_cfg.os != abi::OsMacos {
|
||||
if !dylib && sess.targ_cfg.os != abi::OsMacos && sess.targ_cfg.os != abi::OsiOS {
|
||||
cmd.arg("-Wl,--gc-sections");
|
||||
}
|
||||
|
||||
@ -1185,7 +1229,7 @@ fn link_args(cmd: &mut Command,
|
||||
sess.opts.optimize == config::Aggressive {
|
||||
cmd.arg("-Wl,-O1");
|
||||
}
|
||||
} else if sess.targ_cfg.os == abi::OsMacos {
|
||||
} else if sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS {
|
||||
// The dead_strip option to the linker specifies that functions and data
|
||||
// unreachable by the entry point will be removed. This is quite useful
|
||||
// with Rust's compilation model of compiling libraries at a time into
|
||||
@ -1348,7 +1392,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
|
||||
// For those that support this, we ensure we pass the option if the library
|
||||
// was flagged "static" (most defaults are dynamic) to ensure that if
|
||||
// libfoo.a and libfoo.so both exist that the right one is chosen.
|
||||
let takes_hints = sess.targ_cfg.os != abi::OsMacos;
|
||||
let takes_hints = sess.targ_cfg.os != abi::OsMacos && sess.targ_cfg.os != abi::OsiOS;
|
||||
|
||||
for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
|
||||
match kind {
|
||||
|
@ -9,17 +9,12 @@
|
||||
// except according to those terms.
|
||||
|
||||
use back::target_strs;
|
||||
use driver::config::cfg_os_to_meta_os;
|
||||
use metadata::loader::meta_section_name;
|
||||
use syntax::abi;
|
||||
|
||||
pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
|
||||
return target_strs::t {
|
||||
module_asm: "".to_string(),
|
||||
|
||||
meta_sect_name:
|
||||
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
|
||||
|
||||
data_layout: match target_os {
|
||||
abi::OsMacos => {
|
||||
"E-p:32:32:32\
|
||||
@ -29,6 +24,14 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
|
||||
-a0:0:64-n32".to_string()
|
||||
}
|
||||
|
||||
abi::OsiOS => {
|
||||
"E-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string()
|
||||
}
|
||||
|
||||
abi::OsWin32 => {
|
||||
"E-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
|
@ -122,7 +122,7 @@ pub fn get_rpath_relative_to_output(os: abi::Os,
|
||||
abi::OsAndroid | abi::OsLinux | abi::OsFreebsd
|
||||
=> "$ORIGIN",
|
||||
abi::OsMacos => "@loader_path",
|
||||
abi::OsWin32 => unreachable!()
|
||||
abi::OsWin32 | abi::OsiOS => unreachable!()
|
||||
};
|
||||
|
||||
let mut lib = fs::realpath(&os::make_absolute(lib)).unwrap();
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
pub struct t {
|
||||
pub module_asm: String,
|
||||
pub meta_sect_name: String,
|
||||
pub data_layout: String,
|
||||
pub target_triple: String,
|
||||
pub cc_args: Vec<String> ,
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
|
||||
use back::target_strs;
|
||||
use driver::config::cfg_os_to_meta_os;
|
||||
use metadata::loader::meta_section_name;
|
||||
use syntax::abi;
|
||||
|
||||
pub fn get_target_strs(target_triple: String, target_os: abi::Os)
|
||||
@ -19,9 +17,6 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os)
|
||||
return target_strs::t {
|
||||
module_asm: "".to_string(),
|
||||
|
||||
meta_sect_name:
|
||||
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
|
||||
|
||||
data_layout: match target_os {
|
||||
abi::OsMacos => {
|
||||
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
|
||||
@ -31,6 +26,14 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os)
|
||||
-n8:16:32".to_string()
|
||||
}
|
||||
|
||||
abi::OsiOS => {
|
||||
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
|
||||
-i32:32:32-i64:32:64\
|
||||
-f32:32:32-f64:32:64-v64:64:64\
|
||||
-v128:128:128-a0:0:64-f80:128:128\
|
||||
-n8:16:32".to_string()
|
||||
}
|
||||
|
||||
abi::OsWin32 => {
|
||||
"e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string()
|
||||
}
|
||||
|
@ -10,17 +10,12 @@
|
||||
|
||||
|
||||
use back::target_strs;
|
||||
use driver::config::cfg_os_to_meta_os;
|
||||
use metadata::loader::meta_section_name;
|
||||
use syntax::abi;
|
||||
|
||||
pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
|
||||
return target_strs::t {
|
||||
module_asm: "".to_string(),
|
||||
|
||||
meta_sect_name:
|
||||
meta_section_name(cfg_os_to_meta_os(target_os)).to_string(),
|
||||
|
||||
data_layout: match target_os {
|
||||
abi::OsMacos => {
|
||||
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
@ -28,6 +23,12 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
|
||||
s0:64:64-f80:128:128-n8:16:32:64".to_string()
|
||||
}
|
||||
|
||||
abi::OsiOS => {
|
||||
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
|
||||
s0:64:64-f80:128:128-n8:16:32:64".to_string()
|
||||
}
|
||||
|
||||
abi::OsWin32 => {
|
||||
// FIXME: Test this. Copied from linux (#2398)
|
||||
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
|
@ -19,7 +19,6 @@ use back;
|
||||
use back::link;
|
||||
use back::target_strs;
|
||||
use back::{arm, x86, x86_64, mips};
|
||||
use metadata;
|
||||
use middle::lint;
|
||||
|
||||
use syntax::abi;
|
||||
@ -36,6 +35,7 @@ use getopts::{optopt, optmulti, optflag, optflagopt};
|
||||
use getopts;
|
||||
use lib::llvm::llvm;
|
||||
use std::cell::{RefCell};
|
||||
use std::fmt;
|
||||
|
||||
|
||||
pub struct Config {
|
||||
@ -357,18 +357,6 @@ pub fn default_lib_output() -> CrateType {
|
||||
CrateTypeRlib
|
||||
}
|
||||
|
||||
pub fn cfg_os_to_meta_os(os: abi::Os) -> metadata::loader::Os {
|
||||
use metadata::loader;
|
||||
|
||||
match os {
|
||||
abi::OsWin32 => loader::OsWin32,
|
||||
abi::OsLinux => loader::OsLinux,
|
||||
abi::OsAndroid => loader::OsAndroid,
|
||||
abi::OsMacos => loader::OsMacos,
|
||||
abi::OsFreebsd => loader::OsFreebsd
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
|
||||
let tos = match sess.targ_cfg.os {
|
||||
abi::OsWin32 => InternedString::new("win32"),
|
||||
@ -376,6 +364,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
|
||||
abi::OsLinux => InternedString::new("linux"),
|
||||
abi::OsAndroid => InternedString::new("android"),
|
||||
abi::OsFreebsd => InternedString::new("freebsd"),
|
||||
abi::OsiOS => InternedString::new("ios"),
|
||||
};
|
||||
|
||||
// ARM is bi-endian, however using NDK seems to default
|
||||
@ -441,7 +430,8 @@ static os_names : &'static [(&'static str, abi::Os)] = &'static [
|
||||
("darwin", abi::OsMacos),
|
||||
("android", abi::OsAndroid),
|
||||
("linux", abi::OsLinux),
|
||||
("freebsd", abi::OsFreebsd)];
|
||||
("freebsd", abi::OsFreebsd),
|
||||
("ios", abi::OsiOS)];
|
||||
|
||||
pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
|
||||
for &(arch, abi) in architecture_abis.iter() {
|
||||
@ -775,6 +765,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for CrateType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
CrateTypeExecutable => "bin".fmt(f),
|
||||
CrateTypeDylib => "dylib".fmt(f),
|
||||
CrateTypeRlib => "rlib".fmt(f),
|
||||
CrateTypeStaticlib => "staticlib".fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
@ -794,17 +794,26 @@ pub fn collect_crate_types(session: &Session,
|
||||
// command line, then reuse the empty `base` Vec to hold the types that
|
||||
// will be found in crate attributes.
|
||||
let mut base = session.opts.crate_types.clone();
|
||||
if base.len() > 0 {
|
||||
return base
|
||||
} else {
|
||||
if base.len() == 0 {
|
||||
base.extend(attr_types.move_iter());
|
||||
if base.len() == 0 {
|
||||
base.push(config::CrateTypeExecutable);
|
||||
base.push(link::default_output_for_target(session));
|
||||
}
|
||||
base.as_mut_slice().sort();
|
||||
base.dedup();
|
||||
return base;
|
||||
}
|
||||
|
||||
base.move_iter().filter(|crate_type| {
|
||||
let res = !link::invalid_output_for_target(session, *crate_type);
|
||||
|
||||
if !res {
|
||||
session.warn(format!("dropping unsupported crate type `{}` \
|
||||
for target os `{}`",
|
||||
*crate_type, session.targ_cfg.os).as_slice());
|
||||
}
|
||||
|
||||
res
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub struct OutputFilenames {
|
||||
|
@ -349,8 +349,7 @@ pub fn early_error(msg: &str) -> ! {
|
||||
|
||||
pub fn list_metadata(sess: &Session, path: &Path,
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
metadata::loader::list_file_metadata(
|
||||
config::cfg_os_to_meta_os(sess.targ_cfg.os), path, out)
|
||||
metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
|
||||
}
|
||||
|
||||
/// Run a procedure which will detect failures in the compiler and print nicer
|
||||
|
@ -250,4 +250,3 @@ pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> String)
|
||||
-> T {
|
||||
diagnostic::expect(sess.diagnostic(), opt, msg)
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
||||
Some(k) => {
|
||||
if k.equiv(&("static")) {
|
||||
cstore::NativeStatic
|
||||
} else if e.sess.targ_cfg.os == abi::OsMacos &&
|
||||
} else if (e.sess.targ_cfg.os == abi::OsMacos ||
|
||||
e.sess.targ_cfg.os == abi::OsiOS) &&
|
||||
k.equiv(&("framework")) {
|
||||
cstore::NativeFramework
|
||||
} else if k.equiv(&("framework")) {
|
||||
@ -345,7 +346,7 @@ fn resolve_crate<'a>(e: &mut Env,
|
||||
id_hash: id_hash.as_slice(),
|
||||
hash: hash.map(|a| &*a),
|
||||
filesearch: e.sess.target_filesearch(),
|
||||
os: config::cfg_os_to_meta_os(e.sess.targ_cfg.os),
|
||||
os: e.sess.targ_cfg.os,
|
||||
triple: e.sess.targ_cfg.target_strs.target_triple.as_slice(),
|
||||
root: root,
|
||||
rejected_via_hash: vec!(),
|
||||
@ -409,7 +410,7 @@ impl<'a> PluginMetadataReader<'a> {
|
||||
hash: None,
|
||||
filesearch: self.env.sess.host_filesearch(),
|
||||
triple: driver::host_triple(),
|
||||
os: config::cfg_os_to_meta_os(os),
|
||||
os: os,
|
||||
root: &None,
|
||||
rejected_via_hash: vec!(),
|
||||
rejected_via_triple: vec!(),
|
||||
@ -420,7 +421,7 @@ impl<'a> PluginMetadataReader<'a> {
|
||||
// try loading from target crates (only valid if there are
|
||||
// no syntax extensions)
|
||||
load_ctxt.triple = target_triple;
|
||||
load_ctxt.os = config::cfg_os_to_meta_os(self.env.sess.targ_cfg.os);
|
||||
load_ctxt.os = self.env.sess.targ_cfg.os;
|
||||
load_ctxt.filesearch = self.env.sess.target_filesearch();
|
||||
let lib = load_ctxt.load_library_crate();
|
||||
if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {
|
||||
|
@ -18,6 +18,7 @@ use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
|
||||
use metadata::decoder;
|
||||
use metadata::encoder;
|
||||
use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
||||
use syntax::abi;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::crateid::CrateId;
|
||||
@ -51,14 +52,6 @@ pub static FREEBSD_DLL_SUFFIX: &'static str = ".so";
|
||||
pub static ANDROID_DLL_PREFIX: &'static str = "lib";
|
||||
pub static ANDROID_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub enum Os {
|
||||
OsMacos,
|
||||
OsWin32,
|
||||
OsLinux,
|
||||
OsAndroid,
|
||||
OsFreebsd
|
||||
}
|
||||
|
||||
pub struct CrateMismatch {
|
||||
path: Path,
|
||||
got: String,
|
||||
@ -72,7 +65,7 @@ pub struct Context<'a> {
|
||||
pub id_hash: &'a str,
|
||||
pub hash: Option<&'a Svh>,
|
||||
pub triple: &'a str,
|
||||
pub os: Os,
|
||||
pub os: abi::Os,
|
||||
pub filesearch: FileSearch<'a>,
|
||||
pub root: &'a Option<CratePaths>,
|
||||
pub rejected_via_hash: Vec<CrateMismatch>,
|
||||
@ -183,10 +176,12 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
|
||||
fn find_library_crate(&mut self) -> Option<Library> {
|
||||
let (dyprefix, dysuffix) = self.dylibname();
|
||||
let dypair = self.dylibname();
|
||||
|
||||
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
||||
let dylib_prefix = format!("{}{}-", dyprefix, self.crate_id.name);
|
||||
let dylib_prefix = dypair.map(|(prefix, _)| {
|
||||
format!("{}{}-", prefix, self.crate_id.name)
|
||||
});
|
||||
let rlib_prefix = format!("lib{}-", self.crate_id.name);
|
||||
|
||||
let mut candidates = HashMap::new();
|
||||
@ -227,12 +222,14 @@ impl<'a> Context<'a> {
|
||||
FileDoesntMatch
|
||||
}
|
||||
}
|
||||
} else if file.starts_with(dylib_prefix.as_slice()) &&
|
||||
file.ends_with(dysuffix){
|
||||
} else if dypair.map_or(false, |(_, suffix)| {
|
||||
file.starts_with(dylib_prefix.get_ref().as_slice()) &&
|
||||
file.ends_with(suffix)
|
||||
}) {
|
||||
let (_, suffix) = dypair.unwrap();
|
||||
let dylib_prefix = dylib_prefix.get_ref().as_slice();
|
||||
info!("dylib candidate: {}", path.display());
|
||||
match self.try_match(file,
|
||||
dylib_prefix.as_slice(),
|
||||
dysuffix) {
|
||||
match self.try_match(file, dylib_prefix, suffix) {
|
||||
Some(hash) => {
|
||||
info!("dylib accepted, hash: {}", hash);
|
||||
let slot = candidates.find_or_insert_with(hash, |_| {
|
||||
@ -457,13 +454,14 @@ impl<'a> Context<'a> {
|
||||
|
||||
// Returns the corresponding (prefix, suffix) that files need to have for
|
||||
// dynamic libraries
|
||||
fn dylibname(&self) -> (&'static str, &'static str) {
|
||||
fn dylibname(&self) -> Option<(&'static str, &'static str)> {
|
||||
match self.os {
|
||||
OsWin32 => (WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX),
|
||||
OsMacos => (MACOS_DLL_PREFIX, MACOS_DLL_SUFFIX),
|
||||
OsLinux => (LINUX_DLL_PREFIX, LINUX_DLL_SUFFIX),
|
||||
OsAndroid => (ANDROID_DLL_PREFIX, ANDROID_DLL_SUFFIX),
|
||||
OsFreebsd => (FREEBSD_DLL_PREFIX, FREEBSD_DLL_SUFFIX),
|
||||
abi::OsWin32 => Some((WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX)),
|
||||
abi::OsMacos => Some((MACOS_DLL_PREFIX, MACOS_DLL_SUFFIX)),
|
||||
abi::OsLinux => Some((LINUX_DLL_PREFIX, LINUX_DLL_SUFFIX)),
|
||||
abi::OsAndroid => Some((ANDROID_DLL_PREFIX, ANDROID_DLL_SUFFIX)),
|
||||
abi::OsFreebsd => Some((FREEBSD_DLL_PREFIX, FREEBSD_DLL_SUFFIX)),
|
||||
abi::OsiOS => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,7 +503,7 @@ impl ArchiveMetadata {
|
||||
}
|
||||
|
||||
// Just a small wrapper to time how long reading metadata takes.
|
||||
fn get_metadata_section(os: Os, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
fn get_metadata_section(os: abi::Os, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
let start = time::precise_time_ns();
|
||||
let ret = get_metadata_section_imp(os, filename);
|
||||
info!("reading {} => {}ms", filename.filename_display(),
|
||||
@ -513,7 +511,7 @@ fn get_metadata_section(os: Os, filename: &Path) -> Result<MetadataBlob, String>
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
if !filename.exists() {
|
||||
return Err(format!("no such file: '{}'", filename.display()));
|
||||
}
|
||||
@ -599,28 +597,30 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, Str
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meta_section_name(os: Os) -> &'static str {
|
||||
pub fn meta_section_name(os: abi::Os) -> Option<&'static str> {
|
||||
match os {
|
||||
OsMacos => "__DATA,__note.rustc",
|
||||
OsWin32 => ".note.rustc",
|
||||
OsLinux => ".note.rustc",
|
||||
OsAndroid => ".note.rustc",
|
||||
OsFreebsd => ".note.rustc"
|
||||
abi::OsMacos => Some("__DATA,__note.rustc"),
|
||||
abi::OsiOS => Some("__DATA,__note.rustc"),
|
||||
abi::OsWin32 => Some(".note.rustc"),
|
||||
abi::OsLinux => Some(".note.rustc"),
|
||||
abi::OsAndroid => Some(".note.rustc"),
|
||||
abi::OsFreebsd => Some(".note.rustc")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_meta_section_name(os: Os) -> &'static str {
|
||||
pub fn read_meta_section_name(os: abi::Os) -> &'static str {
|
||||
match os {
|
||||
OsMacos => "__note.rustc",
|
||||
OsWin32 => ".note.rustc",
|
||||
OsLinux => ".note.rustc",
|
||||
OsAndroid => ".note.rustc",
|
||||
OsFreebsd => ".note.rustc"
|
||||
abi::OsMacos => "__note.rustc",
|
||||
abi::OsiOS => unreachable!(),
|
||||
abi::OsWin32 => ".note.rustc",
|
||||
abi::OsLinux => ".note.rustc",
|
||||
abi::OsAndroid => ".note.rustc",
|
||||
abi::OsFreebsd => ".note.rustc"
|
||||
}
|
||||
}
|
||||
|
||||
// A diagnostic function for dumping crate metadata to an output stream
|
||||
pub fn list_file_metadata(os: Os, path: &Path,
|
||||
pub fn list_file_metadata(os: abi::Os, path: &Path,
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
match get_metadata_section(os, path) {
|
||||
Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
|
||||
|
@ -35,7 +35,7 @@ use driver::driver::{CrateAnalysis, CrateTranslation};
|
||||
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
|
||||
use lib::llvm::{llvm, Vector};
|
||||
use lib;
|
||||
use metadata::{csearch, encoder};
|
||||
use metadata::{csearch, encoder, loader};
|
||||
use middle::lint;
|
||||
use middle::astencode;
|
||||
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
||||
@ -173,12 +173,12 @@ impl<'a> Drop for StatRecorder<'a> {
|
||||
}
|
||||
|
||||
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
|
||||
fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
|
||||
fn decl_fn(ccx: &CrateContext, name: &str, cc: lib::llvm::CallConv,
|
||||
ty: Type, output: ty::t) -> ValueRef {
|
||||
|
||||
let llfn: ValueRef = name.with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
|
||||
llvm::LLVMGetOrInsertFunction(ccx.llmod, buf, ty.to_ref())
|
||||
}
|
||||
});
|
||||
|
||||
@ -197,17 +197,20 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
|
||||
lib::llvm::SetFunctionCallConv(llfn, cc);
|
||||
// Function addresses in Rust are never significant, allowing functions to be merged.
|
||||
lib::llvm::SetUnnamedAddr(llfn, true);
|
||||
set_split_stack(llfn);
|
||||
|
||||
if ccx.is_split_stack_supported() {
|
||||
set_split_stack(llfn);
|
||||
}
|
||||
|
||||
llfn
|
||||
}
|
||||
|
||||
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
|
||||
pub fn decl_cdecl_fn(llmod: ModuleRef,
|
||||
pub fn decl_cdecl_fn(ccx: &CrateContext,
|
||||
name: &str,
|
||||
ty: Type,
|
||||
output: ty::t) -> ValueRef {
|
||||
decl_fn(llmod, name, lib::llvm::CCallConv, ty, output)
|
||||
decl_fn(ccx, name, lib::llvm::CCallConv, ty, output)
|
||||
}
|
||||
|
||||
// only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
|
||||
@ -222,7 +225,7 @@ pub fn get_extern_fn(ccx: &CrateContext,
|
||||
Some(n) => return *n,
|
||||
None => {}
|
||||
}
|
||||
let f = decl_fn(ccx.llmod, name, cc, ty, output);
|
||||
let f = decl_fn(ccx, name, cc, ty, output);
|
||||
externs.insert(name.to_string(), f);
|
||||
f
|
||||
}
|
||||
@ -251,7 +254,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
|
||||
};
|
||||
|
||||
let llfty = type_of_rust_fn(ccx, has_env, inputs.as_slice(), output);
|
||||
let llfn = decl_fn(ccx.llmod, name, lib::llvm::CCallConv, llfty, output);
|
||||
let llfn = decl_fn(ccx, name, lib::llvm::CCallConv, llfty, output);
|
||||
let attrs = get_fn_llvm_attributes(ccx, fn_ty);
|
||||
for &(idx, attr) in attrs.iter() {
|
||||
unsafe {
|
||||
@ -1878,7 +1881,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext,
|
||||
llfty: Type) -> ValueRef {
|
||||
debug!("register_fn_llvmty id={} sym={}", node_id, sym);
|
||||
|
||||
let llfn = decl_fn(ccx.llmod, sym.as_slice(), cc, llfty, ty::mk_nil());
|
||||
let llfn = decl_fn(ccx, sym.as_slice(), cc, llfty, ty::mk_nil());
|
||||
finish_register_fn(ccx, sp, sym, node_id, llfn);
|
||||
llfn
|
||||
}
|
||||
@ -1910,7 +1913,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext,
|
||||
let llfty = Type::func([ccx.int_type, Type::i8p(ccx).ptr_to()],
|
||||
&ccx.int_type);
|
||||
|
||||
let llfn = decl_cdecl_fn(ccx.llmod, "main", llfty, ty::mk_nil());
|
||||
let llfn = decl_cdecl_fn(ccx, "main", llfty, ty::mk_nil());
|
||||
let llbb = "top".with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
|
||||
@ -2279,12 +2282,8 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||
});
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||
cx.sess()
|
||||
.targ_cfg
|
||||
.target_strs
|
||||
.meta_sect_name
|
||||
.as_slice()
|
||||
.with_c_str(|buf| {
|
||||
let name = loader::meta_section_name(cx.sess().targ_cfg.os);
|
||||
name.unwrap_or("rust_metadata").with_c_str(|buf| {
|
||||
llvm::LLVMSetSection(llglobal, buf)
|
||||
});
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
use syntax::abi::{OsWin32, OsMacos};
|
||||
use syntax::abi::{OsWin32, OsMacos, OsiOS};
|
||||
use lib::llvm::*;
|
||||
use super::cabi::*;
|
||||
use super::common::*;
|
||||
@ -36,7 +36,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
|
||||
|
||||
enum Strategy { RetValue(Type), RetPointer }
|
||||
let strategy = match ccx.sess().targ_cfg.os {
|
||||
OsWin32 | OsMacos => {
|
||||
OsWin32 | OsMacos | OsiOS => {
|
||||
match llsize_of_alloc(ccx, rty) {
|
||||
1 => RetValue(Type::i8(ccx)),
|
||||
2 => RetValue(Type::i16(ccx)),
|
||||
|
@ -680,7 +680,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
|
||||
Some(llpersonality) => llpersonality,
|
||||
None => {
|
||||
let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
|
||||
let f = base::decl_cdecl_fn(self.ccx.llmod,
|
||||
let f = base::decl_cdecl_fn(self.ccx,
|
||||
"rust_eh_personality",
|
||||
fty,
|
||||
ty::mk_i32());
|
||||
|
@ -8,7 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
use driver::config::NoDebugInfo;
|
||||
use driver::session::Session;
|
||||
use lib::llvm::{ContextRef, ModuleRef, ValueRef};
|
||||
@ -32,6 +31,7 @@ use std::c_str::ToCStr;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::parse::token::InternedString;
|
||||
|
||||
@ -273,20 +273,32 @@ impl CrateContext {
|
||||
None => fail!()
|
||||
}
|
||||
}
|
||||
|
||||
// Although there is an experimental implementation of LLVM which
|
||||
// supports SS on armv7 it wasn't approved by Apple, see:
|
||||
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
|
||||
// It looks like it might be never accepted to upstream LLVM.
|
||||
//
|
||||
// So far the decision was to disable them in default builds
|
||||
// but it could be enabled (with patched LLVM)
|
||||
pub fn is_split_stack_supported(&self) -> bool {
|
||||
let ref cfg = self.sess().targ_cfg;
|
||||
cfg.os != abi::OsiOS || cfg.arch != abi::Arm
|
||||
}
|
||||
}
|
||||
|
||||
fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
|
||||
macro_rules! ifn (
|
||||
($name:expr fn() -> $ret:expr) => (
|
||||
if *key == $name {
|
||||
let f = base::decl_cdecl_fn(ccx.llmod, $name, Type::func([], &$ret), ty::mk_nil());
|
||||
let f = base::decl_cdecl_fn(ccx, $name, Type::func([], &$ret), ty::mk_nil());
|
||||
ccx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||
return Some(f);
|
||||
}
|
||||
);
|
||||
($name:expr fn($($arg:expr),*) -> $ret:expr) => (
|
||||
if *key == $name {
|
||||
let f = base::decl_cdecl_fn(ccx.llmod, $name,
|
||||
let f = base::decl_cdecl_fn(ccx, $name,
|
||||
Type::func([$($arg),*], &$ret), ty::mk_nil());
|
||||
ccx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||
return Some(f);
|
||||
@ -418,7 +430,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
|
||||
// The `if key == $name` is already in ifn!
|
||||
ifn!($name fn($($arg),*) -> $ret);
|
||||
} else if *key == $name {
|
||||
let f = base::decl_cdecl_fn(ccx.llmod, stringify!($cname),
|
||||
let f = base::decl_cdecl_fn(ccx, stringify!($cname),
|
||||
Type::func([$($arg),*], &$ret),
|
||||
ty::mk_nil());
|
||||
ccx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||
|
@ -660,7 +660,8 @@ pub fn finalize(cx: &CrateContext) {
|
||||
// instruct LLVM to emit an older version of dwarf, however,
|
||||
// for OS X to understand. For more info see #11352
|
||||
// This can be overridden using --llvm-opts -dwarf-version,N.
|
||||
if cx.sess().targ_cfg.os == abi::OsMacos {
|
||||
if cx.sess().targ_cfg.os == abi::OsMacos ||
|
||||
cx.sess().targ_cfg.os == abi::OsiOS {
|
||||
"Dwarf Version".with_c_str(
|
||||
|s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2));
|
||||
} else {
|
||||
|
@ -462,7 +462,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
|
||||
t,
|
||||
format!("glue_{}", name).as_slice());
|
||||
debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t));
|
||||
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm.as_slice(), llfnty, ty::mk_nil());
|
||||
let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());
|
||||
note_unique_llvm_symbol(ccx, fn_nm);
|
||||
return llfn;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ mod imp {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
|
@ -145,6 +145,7 @@ mod imp {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "win32")]
|
||||
mod imp {
|
||||
use core::prelude::*;
|
||||
|
@ -156,7 +156,7 @@ pub unsafe fn cleanup() {
|
||||
pub mod shouldnt_be_public {
|
||||
#[cfg(not(test))]
|
||||
pub use super::local_ptr::native::maybe_tls_key;
|
||||
#[cfg(not(windows), not(target_os = "android"))]
|
||||
#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
|
||||
pub use super::local_ptr::compiled::RT_TLS_PTR;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
use libc;
|
||||
|
||||
#[cfg(not(target_arch = "arm"))]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[repr(C)]
|
||||
pub enum _Unwind_Action {
|
||||
_UA_SEARCH_PHASE = 1,
|
||||
@ -61,9 +62,12 @@ pub static unwinder_private_data_size: int = 5;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub static unwinder_private_data_size: int = 2;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[cfg(target_arch = "arm", not(target_os = "ios"))]
|
||||
pub static unwinder_private_data_size: int = 20;
|
||||
|
||||
#[cfg(target_arch = "arm", target_os = "ios")]
|
||||
pub static unwinder_private_data_size: int = 5;
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
pub static unwinder_private_data_size: int = 2;
|
||||
|
||||
@ -89,8 +93,27 @@ extern {}
|
||||
#[link(name = "gcc")]
|
||||
extern {}
|
||||
|
||||
|
||||
extern "C" {
|
||||
// iOS on armv7 uses SjLj exceptions and requires to link
|
||||
// agains corresponding routine (..._SjLj_...)
|
||||
#[cfg(not(target_os = "ios", target_arch = "arm"))]
|
||||
pub fn _Unwind_RaiseException(exception: *_Unwind_Exception)
|
||||
-> _Unwind_Reason_Code;
|
||||
-> _Unwind_Reason_Code;
|
||||
|
||||
#[cfg(target_os = "ios", target_arch = "arm")]
|
||||
fn _Unwind_SjLj_RaiseException(e: *_Unwind_Exception)
|
||||
-> _Unwind_Reason_Code;
|
||||
|
||||
pub fn _Unwind_DeleteException(exception: *_Unwind_Exception);
|
||||
}
|
||||
|
||||
// ... and now we just providing access to SjLj counterspart
|
||||
// through a standard name to hide those details from others
|
||||
// (see also comment above regarding _Unwind_RaiseException)
|
||||
#[cfg(target_os = "ios", target_arch = "arm")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn _Unwind_RaiseException(exc: *_Unwind_Exception)
|
||||
-> _Unwind_Reason_Code {
|
||||
_Unwind_SjLj_RaiseException(exc)
|
||||
}
|
||||
|
@ -24,10 +24,11 @@ use alloc::owned::Box;
|
||||
|
||||
#[cfg(windows)] // mingw-w32 doesn't like thread_local things
|
||||
#[cfg(target_os = "android")] // see #10686
|
||||
#[cfg(target_os = "ios")]
|
||||
pub use self::native::{init, cleanup, put, take, try_take, unsafe_take, exists,
|
||||
unsafe_borrow, try_unsafe_borrow};
|
||||
|
||||
#[cfg(not(windows), not(target_os = "android"))]
|
||||
#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
|
||||
pub use self::compiled::{init, cleanup, put, take, try_take, unsafe_take, exists,
|
||||
unsafe_borrow, try_unsafe_borrow};
|
||||
|
||||
@ -81,7 +82,7 @@ pub unsafe fn borrow<T>() -> Borrowed<T> {
|
||||
/// implemented using LLVM's thread_local attribute which isn't necessarily
|
||||
/// working on all platforms. This implementation is faster, however, so we use
|
||||
/// it wherever possible.
|
||||
#[cfg(not(windows), not(target_os = "android"))]
|
||||
#[cfg(not(windows), not(target_os = "android"), not(target_os = "ios"))]
|
||||
pub mod compiled {
|
||||
use core::prelude::*;
|
||||
|
||||
|
@ -361,6 +361,7 @@ mod imp {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
@ -372,6 +373,10 @@ mod imp {
|
||||
static __PTHREAD_MUTEX_SIZE__: uint = 40;
|
||||
#[cfg(target_arch = "x86")]
|
||||
static __PTHREAD_COND_SIZE__: uint = 24;
|
||||
#[cfg(target_arch = "arm")]
|
||||
static __PTHREAD_MUTEX_SIZE__: uint = 40;
|
||||
#[cfg(target_arch = "arm")]
|
||||
static __PTHREAD_COND_SIZE__: uint = 24;
|
||||
|
||||
static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
|
||||
static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
|
||||
|
@ -24,6 +24,28 @@
|
||||
//! detection is not guaranteed to continue in the future. Usage of this module
|
||||
//! is discouraged unless absolutely necessary.
|
||||
|
||||
// iOS related notes
|
||||
//
|
||||
// It is possible to implement it using idea from
|
||||
// http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h
|
||||
//
|
||||
// In short: _pthread_{get,set}_specific_direct allows extremely fast
|
||||
// access, exactly what is required for segmented stack
|
||||
// There is a pool of reserved slots for Apple internal use (0..119)
|
||||
// First dynamic allocated pthread key starts with 257 (on iOS7)
|
||||
// So using slot 149 should be pretty safe ASSUMING space is reserved
|
||||
// for every key < first dynamic key
|
||||
//
|
||||
// There is also an opportunity to steal keys reserved for Garbage Collection
|
||||
// ranges 80..89 and 110..119, especially considering the fact Garbage Collection
|
||||
// never supposed to work on iOS. But as everybody knows it - there is a chance
|
||||
// that those slots will be re-used, like it happened with key 95 (moved from
|
||||
// JavaScriptCore to CoreText)
|
||||
//
|
||||
// Unfortunately Apple rejected patch to LLVM which generated
|
||||
// corresponding prolog, decision was taken to disable segmented
|
||||
// stack support on iOS.
|
||||
|
||||
pub static RED_ZONE: uint = 20 * 1024;
|
||||
|
||||
/// This function is invoked from rust's current __morestack function. Segmented
|
||||
@ -151,7 +173,8 @@ pub unsafe fn record_sp_limit(limit: uint) {
|
||||
return target_record_sp_limit(limit);
|
||||
|
||||
// x86-64
|
||||
#[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
|
||||
#[cfg(target_arch = "x86_64", target_os = "macos")]
|
||||
#[cfg(target_arch = "x86_64", target_os = "ios")] #[inline(always)]
|
||||
unsafe fn target_record_sp_limit(limit: uint) {
|
||||
asm!("movq $$0x60+90*8, %rsi
|
||||
movq $0, %gs:(%rsi)" :: "r"(limit) : "rsi" : "volatile")
|
||||
@ -173,7 +196,8 @@ pub unsafe fn record_sp_limit(limit: uint) {
|
||||
}
|
||||
|
||||
// x86
|
||||
#[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
|
||||
#[cfg(target_arch = "x86", target_os = "macos")]
|
||||
#[cfg(target_arch = "x86", target_os = "ios")] #[inline(always)]
|
||||
unsafe fn target_record_sp_limit(limit: uint) {
|
||||
asm!("movl $$0x48+90*4, %eax
|
||||
movl $0, %gs:(%eax)" :: "r"(limit) : "eax" : "volatile")
|
||||
@ -193,7 +217,7 @@ pub unsafe fn record_sp_limit(limit: uint) {
|
||||
// mips, arm - Some brave soul can port these to inline asm, but it's over
|
||||
// my head personally
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "arm")] #[inline(always)]
|
||||
#[cfg(target_arch = "arm", not(target_os = "ios"))] #[inline(always)]
|
||||
unsafe fn target_record_sp_limit(limit: uint) {
|
||||
use libc::c_void;
|
||||
return record_sp_limit(limit as *c_void);
|
||||
@ -201,6 +225,11 @@ pub unsafe fn record_sp_limit(limit: uint) {
|
||||
fn record_sp_limit(limit: *c_void);
|
||||
}
|
||||
}
|
||||
|
||||
// iOS segmented stack is disabled for now, see related notes
|
||||
#[cfg(target_arch = "arm", target_os = "ios")] #[inline(always)]
|
||||
unsafe fn target_record_sp_limit(_: uint) {
|
||||
}
|
||||
}
|
||||
|
||||
/// The counterpart of the function above, this function will fetch the current
|
||||
@ -216,7 +245,8 @@ pub unsafe fn get_sp_limit() -> uint {
|
||||
return target_get_sp_limit();
|
||||
|
||||
// x86-64
|
||||
#[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
|
||||
#[cfg(target_arch = "x86_64", target_os = "macos")]
|
||||
#[cfg(target_arch = "x86_64", target_os = "ios")] #[inline(always)]
|
||||
unsafe fn target_get_sp_limit() -> uint {
|
||||
let limit;
|
||||
asm!("movq $$0x60+90*8, %rsi
|
||||
@ -243,7 +273,8 @@ pub unsafe fn get_sp_limit() -> uint {
|
||||
}
|
||||
|
||||
// x86
|
||||
#[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
|
||||
#[cfg(target_arch = "x86", target_os = "macos")]
|
||||
#[cfg(target_arch = "x86", target_os = "ios")] #[inline(always)]
|
||||
unsafe fn target_get_sp_limit() -> uint {
|
||||
let limit;
|
||||
asm!("movl $$0x48+90*4, %eax
|
||||
@ -267,7 +298,7 @@ pub unsafe fn get_sp_limit() -> uint {
|
||||
// mips, arm - Some brave soul can port these to inline asm, but it's over
|
||||
// my head personally
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "arm")] #[inline(always)]
|
||||
#[cfg(target_arch = "arm", not(target_os = "ios"))] #[inline(always)]
|
||||
unsafe fn target_get_sp_limit() -> uint {
|
||||
use libc::c_void;
|
||||
return get_sp_limit() as uint;
|
||||
@ -275,4 +306,12 @@ pub unsafe fn get_sp_limit() -> uint {
|
||||
fn get_sp_limit() -> *c_void;
|
||||
}
|
||||
}
|
||||
|
||||
// iOS doesn't support segmented stacks yet. This function might
|
||||
// be called by runtime though so it is unsafe to mark it as
|
||||
// unreachable, let's return a fixed constant.
|
||||
#[cfg(target_arch = "arm", target_os = "ios")] #[inline(always)]
|
||||
unsafe fn target_get_sp_limit() -> uint {
|
||||
1024
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,6 @@ mod imp {
|
||||
}
|
||||
|
||||
pub unsafe fn yield_now() { assert_eq!(sched_yield(), 0); }
|
||||
|
||||
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
|
||||
// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
|
||||
// storage. We need that information to avoid blowing up when a small stack
|
||||
@ -345,4 +344,3 @@ mod tests {
|
||||
assert_eq!(42, Thread::start_stack(1, proc () 42).join());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,13 +37,14 @@ pub unsafe fn destroy(key: Key) {
|
||||
assert!(pthread_key_delete(key) == 0);
|
||||
}
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
#[cfg(target_os = "macos")]
|
||||
#[allow(non_camel_case_types)] // foreign type
|
||||
type pthread_key_t = ::libc::c_ulong;
|
||||
|
||||
#[cfg(target_os="linux")]
|
||||
#[cfg(target_os="freebsd")]
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[allow(non_camel_case_types)] // foreign type
|
||||
type pthread_key_t = ::libc::c_uint;
|
||||
|
||||
|
@ -283,16 +283,73 @@ pub mod eabi {
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iOS on armv7 is using SjLj exceptions and therefore requires to use
|
||||
// a specialized personality routine: __gcc_personality_sj0
|
||||
|
||||
#[cfg(target_os = "ios", target_arch = "arm", not(test))]
|
||||
#[doc(hidden)]
|
||||
#[allow(visible_private_types)]
|
||||
pub mod eabi {
|
||||
use uw = libunwind;
|
||||
use libc::c_int;
|
||||
|
||||
extern "C" {
|
||||
fn __gcc_personality_sj0(version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context)
|
||||
-> uw::_Unwind_Reason_Code;
|
||||
}
|
||||
|
||||
#[lang="eh_personality"]
|
||||
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
|
||||
pub extern "C" fn rust_eh_personality(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
unsafe {
|
||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle] // referenced from rust_try.ll
|
||||
pub extern "C" fn rust_eh_personality_catch(
|
||||
version: c_int,
|
||||
actions: uw::_Unwind_Action,
|
||||
exception_class: uw::_Unwind_Exception_Class,
|
||||
ue_header: *uw::_Unwind_Exception,
|
||||
context: *uw::_Unwind_Context
|
||||
) -> uw::_Unwind_Reason_Code
|
||||
{
|
||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
||||
uw::_URC_HANDLER_FOUND // catch!
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
||||
context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ARM EHABI uses a slightly different personality routine signature,
|
||||
// but otherwise works the same.
|
||||
#[cfg(target_arch = "arm", not(test))]
|
||||
#[cfg(target_arch = "arm", not(test), not(target_os = "ios"))]
|
||||
#[allow(visible_private_types)]
|
||||
pub mod eabi {
|
||||
use uw = libunwind;
|
||||
@ -330,7 +387,7 @@ pub mod eabi {
|
||||
}
|
||||
else { // cleanup phase
|
||||
unsafe {
|
||||
__gcc_personality_v0(state, ue_header, context)
|
||||
__gcc_personality_v0(state, ue_header, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ impl DynamicLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(test, not(target_os = "ios"))]
|
||||
mod test {
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
@ -206,6 +206,7 @@ mod test {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod dl {
|
||||
use prelude::*;
|
||||
|
@ -552,6 +552,7 @@ pub fn pipe() -> Pipe {
|
||||
|
||||
/// Returns the proper dll filename for the given basename of a file
|
||||
/// as a String.
|
||||
#[cfg(not(target_os="ios"))]
|
||||
pub fn dll_filename(base: &str) -> String {
|
||||
format!("{}{}{}", consts::DLL_PREFIX, base, consts::DLL_SUFFIX)
|
||||
}
|
||||
@ -608,6 +609,7 @@ pub fn self_exe_name() -> Option<Path> {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
fn load_self() -> Option<Vec<u8>> {
|
||||
unsafe {
|
||||
use libc::funcs::extra::_NSGetExecutablePath;
|
||||
@ -802,6 +804,7 @@ pub fn change_dir(p: &Path) -> bool {
|
||||
/// Returns the platform-specific value of errno
|
||||
pub fn errno() -> int {
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn errno_location() -> *c_int {
|
||||
extern {
|
||||
@ -850,6 +853,7 @@ pub fn error_string(errnum: uint) -> String {
|
||||
#[cfg(unix)]
|
||||
fn strerror(errnum: uint) -> String {
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t)
|
||||
@ -995,6 +999,64 @@ fn real_args_as_bytes() -> Vec<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
|
||||
// As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs
|
||||
// and use underscores in their names - they're most probably
|
||||
// are considered private and therefore should be avoided
|
||||
// Here is another way to get arguments using Objective C
|
||||
// runtime
|
||||
//
|
||||
// In general it looks like:
|
||||
// res = Vec::new()
|
||||
// let args = [[NSProcessInfo processInfo] arguments]
|
||||
// for i in range(0, [args count])
|
||||
// res.push([args objectAtIndex:i])
|
||||
// res
|
||||
#[cfg(target_os = "ios")]
|
||||
fn real_args_as_bytes() -> Vec<Vec<u8>> {
|
||||
use c_str::CString;
|
||||
use iter::range;
|
||||
use mem;
|
||||
|
||||
#[link(name = "objc")]
|
||||
extern {
|
||||
fn sel_registerName(name: *libc::c_uchar) -> Sel;
|
||||
fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
|
||||
fn objc_getClass(class_name: *libc::c_uchar) -> NsId;
|
||||
}
|
||||
|
||||
#[link(name = "Foundation", kind = "framework")]
|
||||
extern {}
|
||||
|
||||
type Sel = *libc::c_void;
|
||||
type NsId = *libc::c_void;
|
||||
|
||||
let mut res = Vec::new();
|
||||
|
||||
unsafe {
|
||||
let processInfoSel = sel_registerName("processInfo\0".as_ptr());
|
||||
let argumentsSel = sel_registerName("arguments\0".as_ptr());
|
||||
let utf8Sel = sel_registerName("UTF8String\0".as_ptr());
|
||||
let countSel = sel_registerName("count\0".as_ptr());
|
||||
let objectAtSel = sel_registerName("objectAtIndex:\0".as_ptr());
|
||||
|
||||
let klass = objc_getClass("NSProcessInfo\0".as_ptr());
|
||||
let info = objc_msgSend(klass, processInfoSel);
|
||||
let args = objc_msgSend(info, argumentsSel);
|
||||
|
||||
let cnt: int = mem::transmute(objc_msgSend(args, countSel));
|
||||
for i in range(0, cnt) {
|
||||
let tmp = objc_msgSend(args, objectAtSel, i);
|
||||
let utf_c_str: *libc::c_char = mem::transmute(objc_msgSend(tmp, utf8Sel));
|
||||
let s = CString::new(utf_c_str, false);
|
||||
if s.is_not_null() {
|
||||
res.push(Vec::from_slice(s.as_bytes_no_nul()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
@ -1532,6 +1594,25 @@ pub mod consts {
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `ios`.
|
||||
pub static SYSNAME: &'static str = "ios";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
pub use self::imp::OsRng;
|
||||
|
||||
#[cfg(unix)]
|
||||
#[cfg(unix, not(target_os = "ios"))]
|
||||
mod imp {
|
||||
use io::{IoResult, File};
|
||||
use path::Path;
|
||||
@ -28,7 +28,7 @@ mod imp {
|
||||
/// `/dev/urandom`.
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
///
|
||||
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
|
||||
/// This does not block.
|
||||
#[cfg(unix)]
|
||||
pub struct OsRng {
|
||||
@ -58,6 +58,71 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
mod imp {
|
||||
extern crate libc;
|
||||
|
||||
use collections::Collection;
|
||||
use io::{IoResult};
|
||||
use kinds::marker;
|
||||
use mem;
|
||||
use os;
|
||||
use rand::Rng;
|
||||
use result::{Ok};
|
||||
use self::libc::{c_int, size_t};
|
||||
use slice::MutableVector;
|
||||
|
||||
/// A random number generator that retrieves randomness straight from
|
||||
/// the operating system. Platform sources:
|
||||
///
|
||||
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
|
||||
/// `/dev/urandom`.
|
||||
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
|
||||
/// service provider with the `PROV_RSA_FULL` type.
|
||||
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed
|
||||
/// This does not block.
|
||||
pub struct OsRng {
|
||||
marker: marker::NoCopy
|
||||
}
|
||||
|
||||
struct SecRandom;
|
||||
|
||||
static kSecRandomDefault: *SecRandom = 0 as *SecRandom;
|
||||
|
||||
#[link(name = "Security", kind = "framework")]
|
||||
extern "C" {
|
||||
fn SecRandomCopyBytes(rnd: *SecRandom, count: size_t, bytes: *mut u8) -> c_int;
|
||||
}
|
||||
|
||||
impl OsRng {
|
||||
/// Create a new `OsRng`.
|
||||
pub fn new() -> IoResult<OsRng> {
|
||||
Ok(OsRng {marker: marker::NoCopy} )
|
||||
}
|
||||
}
|
||||
|
||||
impl Rng for OsRng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
let mut v = [0u8, .. 4];
|
||||
self.fill_bytes(v);
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
let mut v = [0u8, .. 8];
|
||||
self.fill_bytes(v);
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
let ret = unsafe {
|
||||
SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
|
||||
};
|
||||
if ret == -1 {
|
||||
fail!("couldn't generate random bytes: {}", os::last_os_error());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod imp {
|
||||
extern crate libc;
|
||||
|
@ -237,22 +237,63 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
|
||||
#[cfg(unix)]
|
||||
mod imp {
|
||||
use c_str::CString;
|
||||
use io::{IoResult, IoError, Writer};
|
||||
use io::{IoResult, Writer};
|
||||
use libc;
|
||||
use mem;
|
||||
use option::{Some, None, Option};
|
||||
use result::{Ok, Err};
|
||||
use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
|
||||
|
||||
struct Context<'a> {
|
||||
idx: int,
|
||||
writer: &'a mut Writer,
|
||||
last_error: Option<IoError>,
|
||||
/// As always - iOS on arm uses SjLj exceptions and
|
||||
/// _Unwind_Backtrace is even not available there. Still,
|
||||
/// backtraces could be extracted using a backtrace function,
|
||||
/// which thanks god is public
|
||||
///
|
||||
/// As mentioned in a huge comment block above, backtrace doesn't
|
||||
/// play well with green threads, so while it is extremely nice
|
||||
/// and simple to use it should be used only on iOS devices as the
|
||||
/// only viable option.
|
||||
#[cfg(target_os = "ios", target_arch = "arm")]
|
||||
#[inline(never)]
|
||||
pub fn write(w: &mut Writer) -> IoResult<()> {
|
||||
use iter::{Iterator, range};
|
||||
use result;
|
||||
use slice::{MutableVector};
|
||||
|
||||
extern {
|
||||
fn backtrace(buf: *mut *libc::c_void, sz: libc::c_int) -> libc::c_int;
|
||||
}
|
||||
|
||||
// while it doesn't requires lock for work as everything is
|
||||
// local, it still displays much nicier backtraces when a
|
||||
// couple of tasks fail simultaneously
|
||||
static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
|
||||
let _g = unsafe { LOCK.lock() };
|
||||
|
||||
try!(writeln!(w, "stack backtrace:"));
|
||||
// 100 lines should be enough
|
||||
static SIZE: libc::c_int = 100;
|
||||
let mut buf: [*libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
|
||||
let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE) as uint};
|
||||
|
||||
// skipping the first one as it is write itself
|
||||
result::fold_(range(1, cnt).map(|i| {
|
||||
print(w, i as int, buf[i])
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "ios", target_arch = "arm"))]
|
||||
#[inline(never)] // if we know this is a function call, we can skip it when
|
||||
// tracing
|
||||
pub fn write(w: &mut Writer) -> IoResult<()> {
|
||||
use io::IoError;
|
||||
|
||||
struct Context<'a> {
|
||||
idx: int,
|
||||
writer: &'a mut Writer,
|
||||
last_error: Option<IoError>,
|
||||
}
|
||||
|
||||
// When using libbacktrace, we use some necessary global state, so we
|
||||
// need to prevent more than one thread from entering this block. This
|
||||
// is semi-reasonable in terms of printing anyway, and we know that all
|
||||
@ -291,7 +332,7 @@ mod imp {
|
||||
// instructions after it. This means that the return instruction
|
||||
// pointer points *outside* of the calling function, and by
|
||||
// unwinding it we go back to the original function.
|
||||
let ip = if cfg!(target_os = "macos") {
|
||||
let ip = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
|
||||
ip
|
||||
} else {
|
||||
unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
|
||||
@ -323,6 +364,7 @@ mod imp {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
|
||||
use intrinsics;
|
||||
#[repr(C)]
|
||||
@ -347,7 +389,7 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "ios"))]
|
||||
fn print(w: &mut Writer, idx: int, addr: *libc::c_void) -> IoResult<()> {
|
||||
use collections::Collection;
|
||||
use iter::Iterator;
|
||||
@ -487,9 +529,14 @@ mod imp {
|
||||
|
||||
/// Unwind library interface used for backtraces
|
||||
///
|
||||
/// Note that the native libraries come from librustrt, not this module.
|
||||
/// Note that the native libraries come from librustrt, not this
|
||||
/// module.
|
||||
/// Note that dead code is allowed as here are just bindings
|
||||
/// iOS doesn't use all of them it but adding more
|
||||
/// platform-specific configs pollutes the code too much
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_snake_case_functions)]
|
||||
#[allow(dead_code)]
|
||||
mod uw {
|
||||
use libc;
|
||||
|
||||
@ -514,6 +561,8 @@ mod imp {
|
||||
arg: *libc::c_void) -> _Unwind_Reason_Code;
|
||||
|
||||
extern {
|
||||
// No native _Unwind_Backtrace on iOS
|
||||
#[cfg(not(target_os = "ios", target_arch = "arm"))]
|
||||
pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
|
||||
trace_argument: *libc::c_void)
|
||||
-> _Unwind_Reason_Code;
|
||||
|
@ -39,3 +39,7 @@ extern {}
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link(name = "System")]
|
||||
extern {}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
#[link(name = "System")]
|
||||
extern {}
|
||||
|
@ -11,7 +11,7 @@
|
||||
use std::fmt;
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
|
||||
pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsiOS, }
|
||||
|
||||
#[deriving(PartialEq, Eq, Hash, Encodable, Decodable, Clone)]
|
||||
pub enum Abi {
|
||||
@ -159,6 +159,19 @@ impl fmt::Show for Abi {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for Os {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
OsLinux => "linux".fmt(f),
|
||||
OsWin32 => "win32".fmt(f),
|
||||
OsMacos => "macos".fmt(f),
|
||||
OsiOS => "ios".fmt(f),
|
||||
OsAndroid => "android".fmt(f),
|
||||
OsFreebsd => "freebsd".fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case_functions)]
|
||||
#[test]
|
||||
fn lookup_Rust() {
|
||||
|
@ -46,7 +46,7 @@ mod rustrt {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix, not(target_os = "macos"))]
|
||||
#[cfg(unix, not(target_os = "macos"), not(target_os = "ios"))]
|
||||
mod imp {
|
||||
use libc::{c_int, timespec};
|
||||
|
||||
@ -61,6 +61,7 @@ mod imp {
|
||||
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
mod imp {
|
||||
use libc::{timeval, timezone, c_int, mach_timebase_info};
|
||||
|
||||
@ -121,6 +122,7 @@ pub fn get_time() -> Timespec {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
unsafe fn os_get_time() -> (i64, i32) {
|
||||
use std::ptr;
|
||||
let mut tv = libc::timeval { tv_sec: 0, tv_usec: 0 };
|
||||
@ -128,7 +130,7 @@ pub fn get_time() -> Timespec {
|
||||
(tv.tv_sec as i64, tv.tv_usec * 1000)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"), not(windows))]
|
||||
#[cfg(not(target_os = "macos"), not(target_os = "ios"), not(windows))]
|
||||
unsafe fn os_get_time() -> (i64, i32) {
|
||||
let mut tv = libc::timespec { tv_sec: 0, tv_nsec: 0 };
|
||||
imp::clock_gettime(libc::CLOCK_REALTIME, &mut tv);
|
||||
@ -160,6 +162,7 @@ pub fn precise_time_ns() -> u64 {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "ios")]
|
||||
fn os_precise_time_ns() -> u64 {
|
||||
static mut TIMEBASE: libc::mach_timebase_info = libc::mach_timebase_info { numer: 0,
|
||||
denom: 0 };
|
||||
@ -173,7 +176,7 @@ pub fn precise_time_ns() -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows), not(target_os = "macos"))]
|
||||
#[cfg(not(windows), not(target_os = "macos"), not(target_os = "ios"))]
|
||||
fn os_precise_time_ns() -> u64 {
|
||||
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
|
||||
unsafe {
|
||||
|
@ -12,8 +12,16 @@
|
||||
.align
|
||||
#endif
|
||||
|
||||
.globl rust_swap_registers
|
||||
rust_swap_registers:
|
||||
#if defined(__APPLE__)
|
||||
#define SWAP_REGISTERS _rust_swap_registers
|
||||
#define BOOTSTRAP_TASK _rust_bootstrap_green_task
|
||||
#else
|
||||
#define SWAP_REGISTERS rust_swap_registers
|
||||
#define BOOTSTRAP_TASK rust_bootstrap_green_task
|
||||
#endif
|
||||
|
||||
.globl SWAP_REGISTERS
|
||||
SWAP_REGISTERS:
|
||||
str r0, [r0, #0]
|
||||
str r3, [r0, #12]
|
||||
str r4, [r0, #16]
|
||||
@ -53,9 +61,9 @@ rust_swap_registers:
|
||||
mov pc, lr
|
||||
|
||||
// For reasons of this existence, see the comments in x86_64/_context.S
|
||||
.globl rust_bootstrap_green_task
|
||||
rust_bootstrap_green_task:
|
||||
mov r0, r0
|
||||
mov r1, r3
|
||||
mov r2, r4
|
||||
mov pc, r5
|
||||
.globl BOOTSTRAP_TASK
|
||||
BOOTSTRAP_TASK:
|
||||
mov r0, r0
|
||||
mov r1, r3
|
||||
mov r2, r4
|
||||
mov pc, r5
|
||||
|
@ -8,33 +8,63 @@
|
||||
.text
|
||||
.code 32
|
||||
.arm
|
||||
#if defined(__APPLE__)
|
||||
.align 2
|
||||
#else
|
||||
.align
|
||||
#endif
|
||||
|
||||
.global rust_stack_exhausted
|
||||
.global __morestack
|
||||
.hidden __morestack
|
||||
#if defined(__APPLE__)
|
||||
#define MORESTACK ___morestack
|
||||
#define STACK_EXHAUSTED _rust_stack_exhausted
|
||||
#else
|
||||
#define MORESTACK __morestack
|
||||
#define STACK_EXHAUSTED rust_stack_exhausted
|
||||
#endif
|
||||
|
||||
.global STACK_EXHAUSTED
|
||||
.global MORESTACK
|
||||
|
||||
// Unfortunately LLVM yet doesn't support emitting correct debug
|
||||
// DWARF information for non-ELF targets so to make it compile
|
||||
// on iOS all that directives are simply commented out
|
||||
#if defined(__APPLE__)
|
||||
#define UNWIND @
|
||||
#else
|
||||
#define UNWIND
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
.private_extern MORESTACK
|
||||
#else
|
||||
.hidden MORESTACK
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
.type MORESTACK,%function
|
||||
#endif
|
||||
|
||||
// r4 and r5 are scratch registers for __morestack due to llvm
|
||||
// ARMFrameLowering::adjustForSegmentedStacks() implementation.
|
||||
.type __morestack,%function
|
||||
__morestack:
|
||||
.fnstart
|
||||
// Save frame pointer and return address
|
||||
.save {r4, r5}
|
||||
.save {lr}
|
||||
.save {r6, fp, lr}
|
||||
MORESTACK:
|
||||
UNWIND .fnstart
|
||||
|
||||
// Save frame pointer and return address
|
||||
UNWIND .save {r4, r5}
|
||||
UNWIND .save {lr}
|
||||
UNWIND .save {r6, fp, lr}
|
||||
push {r6, fp, lr}
|
||||
|
||||
.movsp r6
|
||||
mov r6, sp
|
||||
.setfp fp, sp, #4
|
||||
add fp, sp, #4
|
||||
UNWIND .movsp r6
|
||||
mov r6, sp
|
||||
UNWIND .setfp fp, sp, #4
|
||||
add fp, sp, #4
|
||||
|
||||
// Save argument registers of the original function
|
||||
push {r0, r1, r2, r3, lr}
|
||||
|
||||
// Create new stack
|
||||
bl rust_stack_exhausted@plt
|
||||
bl STACK_EXHAUSTED@plt
|
||||
|
||||
// the above function ensures that it never returns
|
||||
.fnend
|
||||
UNWIND .fnend
|
||||
|
@ -1,3 +1,9 @@
|
||||
// Do not compile anything here for iOS because split stacks
|
||||
// are disabled at all and do not need any runtime support.
|
||||
//
|
||||
// See also comments in librustrt/stack.rs about why it was
|
||||
// disabled and how it could be implemented in case of need.
|
||||
#if !defined(__APPLE__)
|
||||
// Mark stack as non-executable
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack, "", %progbits
|
||||
@ -6,16 +12,15 @@
|
||||
.text
|
||||
.code 32
|
||||
.arm
|
||||
#if defined(__APPLE__)
|
||||
.align 2
|
||||
#else
|
||||
.align
|
||||
#endif
|
||||
|
||||
.globl record_sp_limit
|
||||
.globl get_sp_limit
|
||||
#define RECORD_SP_LIMIT record_sp_limit
|
||||
#define GET_SP_LIMIT get_sp_limit
|
||||
|
||||
record_sp_limit:
|
||||
.globl RECORD_SP_LIMIT
|
||||
.globl GET_SP_LIMIT
|
||||
|
||||
RECORD_SP_LIMIT:
|
||||
// First, try to read TLS address from coprocessor
|
||||
mrc p15, #0, r3, c13, c0, #3
|
||||
cmp r3, #0
|
||||
@ -27,12 +32,12 @@ record_sp_limit:
|
||||
add r3, r3, #252
|
||||
#elif __linux__
|
||||
add r3, r3, #4
|
||||
#endif
|
||||
#endif // ANDROID
|
||||
|
||||
str r0, [r3]
|
||||
mov pc, lr
|
||||
|
||||
get_sp_limit:
|
||||
GET_SP_LIMIT:
|
||||
// First, try to read TLS address from coprocessor
|
||||
mrc p15, #0, r3, c13, c0, #3
|
||||
cmp r3, #0
|
||||
@ -44,7 +49,8 @@ get_sp_limit:
|
||||
add r3, r3, #252
|
||||
#elif __linux__
|
||||
add r3, r3, #4
|
||||
#endif
|
||||
#endif // __ANDROID__
|
||||
|
||||
ldr r0, [r3]
|
||||
mov pc, lr
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user