diff --git a/.gitignore b/.gitignore index ed709c9b2cda..0c22a78c30e1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,3 @@ all_spec /src/llvm/ext/llvm_ext.o /src/llvm/ext/llvm_ext.obj /src/llvm/ext/llvm_ext.dwo -/src/ext/*.o -/src/ext/libcrystal.a diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7a6b7b42319..6a77a16bfd2a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,8 +91,6 @@ Additionally, all official documentation can be found on [the Crystal website](h 1. Fork it ( https://github.com/crystal-lang/crystal/fork ) 2. Clone it -Be sure to execute `make libcrystal` inside the cloned repository. - Once in the cloned directory, and once you [installed Crystal](https://crystal-lang.org/install/), you can execute `bin/crystal` instead of `crystal`. This is a wrapper that will use the cloned repository as the standard library. Otherwise the barebones `crystal` executable uses the standard library that comes in diff --git a/Makefile b/Makefile index cf3ffd900135..cabf2ecca427 100644 --- a/Makefile +++ b/Makefile @@ -42,11 +42,7 @@ SHELL = sh LLVM_CONFIG := $(shell src/llvm/ext/find-llvm-config) LLVM_EXT_DIR = src/llvm/ext LLVM_EXT_OBJ = $(LLVM_EXT_DIR)/llvm_ext.o -LIB_CRYSTAL_SOURCES = $(shell find src/ext -name '*.c') -LIB_CRYSTAL_OBJS = $(subst .c,.o,$(LIB_CRYSTAL_SOURCES)) -LIB_CRYSTAL_TARGET = src/ext/libcrystal.a -DEPS = $(LLVM_EXT_OBJ) $(LIB_CRYSTAL_TARGET) -CFLAGS += -fPIC $(if $(debug),-g -O0) +DEPS = $(LLVM_EXT_OBJ) CXXFLAGS += $(if $(debug),-g -O0) CRYSTAL_VERSION ?= $(shell cat src/VERSION) @@ -99,11 +95,9 @@ docs: ## Generate standard library documentation .PHONY: crystal crystal: $(O)/crystal ## Build the compiler -.PHONY: deps llvm_ext libcrystal +.PHONY: deps llvm_ext deps: $(DEPS) ## Build dependencies - llvm_ext: $(LLVM_EXT_OBJ) -libcrystal: $(LIB_CRYSTAL_TARGET) $(O)/all_spec: $(DEPS) $(SOURCES) $(SPEC_SOURCES) @mkdir -p $(O) @@ -124,13 +118,9 @@ $(O)/crystal: $(DEPS) $(SOURCES) $(LLVM_EXT_OBJ): $(LLVM_EXT_DIR)/llvm_ext.cc $(CXX) -c $(CXXFLAGS) -o $@ $< $(shell $(LLVM_CONFIG) --cxxflags) -$(LIB_CRYSTAL_TARGET): $(LIB_CRYSTAL_OBJS) - $(AR) -rcs $@ $^ - .PHONY: clean clean: clean_crystal ## Clean up built directories and files rm -rf $(LLVM_EXT_OBJ) - rm -rf $(LIB_CRYSTAL_OBJS) $(LIB_CRYSTAL_TARGET) .PHONY: clean_crystal clean_crystal: ## Clean up crystal built files diff --git a/shell.nix b/shell.nix index cc50de036db8..6e5787d14d0b 100644 --- a/shell.nix +++ b/shell.nix @@ -146,6 +146,5 @@ pkgs.stdenv.mkDerivation rec { LLVM_CONFIG = "${llvm_suite.llvm}/bin/llvm-config"; - # ld: warning: object file (.../src/ext/libcrystal.a(sigfault.o)) was built for newer OSX version (10.14) than being linked (10.12) MACOSX_DEPLOYMENT_TARGET = "10.11"; } diff --git a/src/ext.cr b/src/ext.cr deleted file mode 100644 index effe7be28e75..000000000000 --- a/src/ext.cr +++ /dev/null @@ -1,4 +0,0 @@ -@[Link(ldflags: "#{__DIR__}/ext/libcrystal.a")] -lib LibExt - fun setup_sigfault_handler -end diff --git a/src/ext/sigfault.c b/src/ext/sigfault.c deleted file mode 100644 index 5293f3d84304..000000000000 --- a/src/ext/sigfault.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -void __crystal_sigfault_handler(int sig, void *addr); - -void sigfault_handler(int sig, siginfo_t *info, void *data) { - __crystal_sigfault_handler(sig, info->si_addr); -} - -void setup_sigfault_handler() { - stack_t altstack; - struct sigaction action; - - altstack.ss_sp = malloc(SIGSTKSZ); - altstack.ss_size = SIGSTKSZ; - altstack.ss_flags = 0; - sigaltstack(&altstack, NULL); - - sigemptyset(&action.sa_mask); - action.sa_flags = SA_ONSTACK | SA_SIGINFO; - action.sa_sigaction = &sigfault_handler; - - sigaction(SIGSEGV, &action, NULL); - sigaction(SIGBUS, &action, NULL); -} diff --git a/src/kernel.cr b/src/kernel.cr index 60117755d3d6..61b3033ea808 100644 --- a/src/kernel.cr +++ b/src/kernel.cr @@ -535,7 +535,7 @@ end end Signal.setup_default_handlers - LibExt.setup_sigfault_handler + Signal.setup_sigfault_handler {% end %} {% if !flag?(:win32) %} diff --git a/src/lib_c/aarch64-darwin/c/signal.cr b/src/lib_c/aarch64-darwin/c/signal.cr index 74af1891ee06..454487960975 100644 --- a/src/lib_c/aarch64-darwin/c/signal.cr +++ b/src/lib_c/aarch64-darwin/c/signal.cr @@ -33,6 +33,7 @@ lib LibC SIGEMT = 7 SIGINFO = 29 SIGWINCH = 28 + SIGSTKSZ = 131072 SIG_SETMASK = 3 @@ -42,9 +43,41 @@ lib LibC SIG_DFL = SighandlerT.new(Pointer(Void).new(0_u64), Pointer(Void).null) SIG_IGN = SighandlerT.new(Pointer(Void).new(1_u64), Pointer(Void).null) + SA_ONSTACK = 0x0001 + SA_SIGINFO = 0x0040 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_pid : PidT + si_uid : UidT + si_status : Int + si_addr : Void* + _pad : StaticArray(SizeT, 9) + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + # Technically a union, but only one can be valid and we only use sa_sigaction + # and not sa_handler (which would be a SighandlerT) + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + end + + struct StackT + ss_sp : Void* + ss_size : SizeT + ss_flags : Int + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/aarch64-linux-gnu/c/signal.cr b/src/lib_c/aarch64-linux-gnu/c/signal.cr index 325fdb8cf457..56bb186a4aaf 100644 --- a/src/lib_c/aarch64-linux-gnu/c/signal.cr +++ b/src/lib_c/aarch64-linux-gnu/c/signal.cr @@ -35,6 +35,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = 31 + SIGSTKSZ = 16384 SIG_SETMASK = 2 @@ -46,9 +47,38 @@ lib LibC val : ULong[32] # (1024 / (8 * sizeof(long))) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + __pad0 : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad1 : StaticArray(Int, 20) # __SI_PAD_SIZE (28) - sizeof(void*) (8) = 20 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(pid : PidT, sig : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(sig : Int, handler : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/aarch64-linux-musl/c/signal.cr b/src/lib_c/aarch64-linux-musl/c/signal.cr index a66eac510650..7ba81faf102a 100644 --- a/src/lib_c/aarch64-linux-musl/c/signal.cr +++ b/src/lib_c/aarch64-linux-musl/c/signal.cr @@ -34,6 +34,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = LibC::SIGSYS + SIGSTKSZ = 12288 SIG_SETMASK = 2 @@ -45,9 +46,38 @@ lib LibC val : ULong[16] # 128 / sizeof(long) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + __pad0 : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad1 : StaticArray(Int, 20) # __SI_PAD_SIZE (28) - sizeof(void*) (8) = 20 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/arm-linux-gnueabihf/c/signal.cr b/src/lib_c/arm-linux-gnueabihf/c/signal.cr index 325fdb8cf457..c53b6e4619b5 100644 --- a/src/lib_c/arm-linux-gnueabihf/c/signal.cr +++ b/src/lib_c/arm-linux-gnueabihf/c/signal.cr @@ -35,6 +35,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = 31 + SIGSTKSZ = 8192 SIG_SETMASK = 2 @@ -46,9 +47,37 @@ lib LibC val : ULong[32] # (1024 / (8 * sizeof(long))) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad : StaticArray(Int, 25) # __SI_PAD_SIZE (29) - sizeof(void*) (4) = 25 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(pid : PidT, sig : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(sig : Int, handler : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/i386-linux-gnu/c/signal.cr b/src/lib_c/i386-linux-gnu/c/signal.cr index 325fdb8cf457..c53b6e4619b5 100644 --- a/src/lib_c/i386-linux-gnu/c/signal.cr +++ b/src/lib_c/i386-linux-gnu/c/signal.cr @@ -35,6 +35,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = 31 + SIGSTKSZ = 8192 SIG_SETMASK = 2 @@ -46,9 +47,37 @@ lib LibC val : ULong[32] # (1024 / (8 * sizeof(long))) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad : StaticArray(Int, 25) # __SI_PAD_SIZE (29) - sizeof(void*) (4) = 25 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(pid : PidT, sig : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(sig : Int, handler : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/i386-linux-musl/c/signal.cr b/src/lib_c/i386-linux-musl/c/signal.cr index df01a297bc4d..2b4163398137 100644 --- a/src/lib_c/i386-linux-musl/c/signal.cr +++ b/src/lib_c/i386-linux-musl/c/signal.cr @@ -34,6 +34,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = LibC::SIGSYS + SIGSTKSZ = 8192 SIG_SETMASK = 2 @@ -45,9 +46,37 @@ lib LibC bits : ULong[32] # 128 / sizeof(long) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad : StaticArray(Int, 25) # __SI_PAD_SIZE (29) - sizeof(void*) (4) = 25 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-darwin/c/signal.cr b/src/lib_c/x86_64-darwin/c/signal.cr index 74af1891ee06..454487960975 100644 --- a/src/lib_c/x86_64-darwin/c/signal.cr +++ b/src/lib_c/x86_64-darwin/c/signal.cr @@ -33,6 +33,7 @@ lib LibC SIGEMT = 7 SIGINFO = 29 SIGWINCH = 28 + SIGSTKSZ = 131072 SIG_SETMASK = 3 @@ -42,9 +43,41 @@ lib LibC SIG_DFL = SighandlerT.new(Pointer(Void).new(0_u64), Pointer(Void).null) SIG_IGN = SighandlerT.new(Pointer(Void).new(1_u64), Pointer(Void).null) + SA_ONSTACK = 0x0001 + SA_SIGINFO = 0x0040 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_pid : PidT + si_uid : UidT + si_status : Int + si_addr : Void* + _pad : StaticArray(SizeT, 9) + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + # Technically a union, but only one can be valid and we only use sa_sigaction + # and not sa_handler (which would be a SighandlerT) + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + end + + struct StackT + ss_sp : Void* + ss_size : SizeT + ss_flags : Int + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-dragonfly/c/signal.cr b/src/lib_c/x86_64-dragonfly/c/signal.cr index 54baf1d21984..2f13728566ba 100644 --- a/src/lib_c/x86_64-dragonfly/c/signal.cr +++ b/src/lib_c/x86_64-dragonfly/c/signal.cr @@ -37,6 +37,7 @@ lib LibC SIGTHR = 32 SIGCKPT = 33 SIGCKPTEXIT = 34 + SIGSTKSZ = 40960 SIG_SETMASK = 3 @@ -48,9 +49,48 @@ lib LibC bits : UInt32[4] end + SA_ONSTACK = 0x0001 + SA_SIGINFO = 0x0040 + + struct Sigval + # Actually a union of an int and a void* + _sival_ptr : Void* + end + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_pid : PidT + si_uid : UidT + si_status : Int + si_addr : Void* + si_value : Sigval + _pad1 : Long + _pad2 : StaticArray(Int, 7) + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + # Technically a union, but only one can be valid and we only use sa_sigaction + # and not sa_handler (which would be a SighandlerT) + sa_sigaction : SigactionHandlerT + sa_flags : Int + sa_mask : SigsetT + end + + struct StackT + ss_sp : Void* + ss_size : SizeT + ss_flags : Int + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-freebsd/c/signal.cr b/src/lib_c/x86_64-freebsd/c/signal.cr index 58ed84355d64..369153956b45 100644 --- a/src/lib_c/x86_64-freebsd/c/signal.cr +++ b/src/lib_c/x86_64-freebsd/c/signal.cr @@ -33,6 +33,7 @@ lib LibC SIGEMT = 7 SIGINFO = 29 SIGWINCH = 28 + SIGSTKSZ = 2048 + 32768 # MINSIGSTKSZ + 32768 SIG_SETMASK = 3 @@ -44,9 +45,48 @@ lib LibC bits : UInt32[4] end + SA_ONSTACK = 0x0001 + SA_SIGINFO = 0x0040 + + struct Sigval + # Actually a union of an int and a void* + _sival_ptr : Void* + end + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + si_pid : PidT + si_uid : UidT + si_status : Int + si_addr : Void* + si_value : Sigval + _pad1 : Long + _pad2 : StaticArray(Int, 7) + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + # Technically a union, but only one can be valid and we only use sa_sigaction + # and not sa_handler (which would be a SighandlerT) + sa_sigaction : SigactionHandlerT + sa_flags : Int + sa_mask : SigsetT + end + + struct StackT + ss_sp : Void* + ss_size : SizeT + ss_flags : Int + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-linux-gnu/c/signal.cr b/src/lib_c/x86_64-linux-gnu/c/signal.cr index 87d6a372ba3c..ff951f8711a3 100644 --- a/src/lib_c/x86_64-linux-gnu/c/signal.cr +++ b/src/lib_c/x86_64-linux-gnu/c/signal.cr @@ -35,6 +35,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = 31 + SIGSTKSZ = 8192 SIG_SETMASK = 2 @@ -46,9 +47,38 @@ lib LibC val : ULong[16] # (1024 / (8 * sizeof(ULong))) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + __pad0 : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad1 : StaticArray(Int, 20) # __SI_PAD_SIZE (28) - sizeof(void*) (8) = 20 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(pid : PidT, sig : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(sig : Int, handler : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-linux-musl/c/signal.cr b/src/lib_c/x86_64-linux-musl/c/signal.cr index f13190050469..c6e863be0ec6 100644 --- a/src/lib_c/x86_64-linux-musl/c/signal.cr +++ b/src/lib_c/x86_64-linux-musl/c/signal.cr @@ -34,6 +34,7 @@ lib LibC SIGPWR = 30 SIGSTKFLT = 16 SIGUNUSED = LibC::SIGSYS + SIGSTKSZ = 8192 SIG_SETMASK = 2 @@ -45,9 +46,38 @@ lib LibC bits : ULong[16] # 128 / sizeof(long) end + SA_ONSTACK = 0x08000000 + SA_SIGINFO = 0x00000004 + + struct SiginfoT + si_signo : Int + si_errno : Int + si_code : Int + __pad0 : Int + si_addr : Void* # Assuming the sigfault form of siginfo_t + __pad1 : StaticArray(Int, 20) # __SI_PAD_SIZE (28) - sizeof(void*) (8) = 20 + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + sa_sigaction : SigactionHandlerT + sa_mask : SigsetT + sa_flags : Int + sa_restorer : Void* + end + + struct StackT + ss_sp : Void* + ss_flags : Int + ss_size : SizeT + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-netbsd/c/signal.cr b/src/lib_c/x86_64-netbsd/c/signal.cr index a9d866834f17..557c6a678255 100644 --- a/src/lib_c/x86_64-netbsd/c/signal.cr +++ b/src/lib_c/x86_64-netbsd/c/signal.cr @@ -33,6 +33,7 @@ lib LibC SIGUSR2 = 31 SIGINFO = 29 SIGWINCH = 28 + SIGSTKSZ = 40960 SIG_SETMASK = 3 @@ -44,9 +45,39 @@ lib LibC bits : UInt32[4] end + SA_ONSTACK = 0x0001 + SA_SIGINFO = 0x0040 + + struct SiginfoT + si_signo : Int + si_code : Int + si_errno : Int + _pad1 : Int + si_addr : Void* + _pad2 : StaticArray(UInt64, 13) + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + # Technically a union, but only one can be valid and we only use sa_sigaction + # and not sa_handler (which would be a SighandlerT) + sa_sigaction : SigactionHandlerT + sa_flags : Int + sa_mask : SigsetT + end + + struct StackT + ss_sp : Void* + ss_size : SizeT + ss_flags : Int + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction = __sigaction14(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack = __sigaltstack14(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset = __sigemptyset14(SigsetT*) : Int fun sigfillset = __sigfillset14(SigsetT*) : Int fun sigaddset = __sigaddset14(SigsetT*, Int) : Int diff --git a/src/lib_c/x86_64-openbsd/c/signal.cr b/src/lib_c/x86_64-openbsd/c/signal.cr index d28423d828a7..291253fca963 100644 --- a/src/lib_c/x86_64-openbsd/c/signal.cr +++ b/src/lib_c/x86_64-openbsd/c/signal.cr @@ -34,6 +34,10 @@ lib LibC SIGINFO = 29 SIGWINCH = 28 + _MAX_PAGE_SHIFT = 12_u32 + MINSIGSTKSZ : SizeT = 3_u64 << _MAX_PAGE_SHIFT + SIGSTKSZ : SizeT = MINSIGSTKSZ + (1_u64 << _MAX_PAGE_SHIFT) * 4 + SIG_SETMASK = 3 alias SighandlerT = Int -> @@ -42,6 +46,27 @@ lib LibC SIG_DFL = SighandlerT.new(Pointer(Void).new(0_u64), Pointer(Void).null) SIG_IGN = SighandlerT.new(Pointer(Void).new(1_u64), Pointer(Void).null) + SA_ONSTACK = 0x0001 + SA_SIGINFO = 0x0040 + + struct SiginfoT + si_signo : Int + si_code : Int + si_errno : Int + si_addr : Char* + _pad : StaticArray(UInt8, 108) + end + + alias SigactionHandlerT = (Int, SiginfoT*, Void*) -> + + struct Sigaction + # Technically a union, but only one can be valid and we only use sa_sigaction + # and not sa_handler (which would be a SighandlerT) + sa_sigaction : SigactionHandlerT + sa_flags : Int + sa_mask : SigsetT + end + struct StackT ss_sp : Void* ss_size : SizeT @@ -51,6 +76,8 @@ lib LibC fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void + fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int + fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int fun sigemptyset(SigsetT*) : Int fun sigfillset(SigsetT*) : Int fun sigaddset(SigsetT*, Int) : Int diff --git a/src/prelude.cr b/src/prelude.cr index 5ccd0f959358..8b6f18377ac2 100644 --- a/src/prelude.cr +++ b/src/prelude.cr @@ -41,7 +41,6 @@ require "enum" require "enumerable" require "env" require "errno" -require "ext" require "file" require "float" require "gc" diff --git a/src/signal.cr b/src/signal.cr index ca2738cd4f62..264496f3b052 100644 --- a/src/signal.cr +++ b/src/signal.cr @@ -56,6 +56,7 @@ enum Signal : Int32 USR1 = LibC::SIGUSR1 USR2 = LibC::SIGUSR2 WINCH = LibC::SIGWINCH + STKSZ = LibC::SIGSTKSZ {% if flag?(:linux) %} PWR = LibC::SIGPWR @@ -123,6 +124,10 @@ enum Signal : Int32 end @@setup_default_handlers = Atomic::Flag.new + @@setup_sigfault_handler = Atomic::Flag.new + @@sigfault_handler = LibC::SigactionHandlerT.new { |sig, info, data| + __crystal_sigfault_handler(sig, info.value.si_addr) + } # :nodoc: def self.setup_default_handlers @@ -132,6 +137,28 @@ enum Signal : Int32 Signal::PIPE.ignore Signal::CHLD.reset end + + # :nodoc: + def self.setup_sigfault_handler + return unless @@setup_sigfault_handler.test_and_set + + altstack = LibC::StackT.new + action = LibC::Sigaction.new + + altstack.ss_sp = LibC.malloc(STKSZ) + altstack.ss_size = STKSZ + altstack.ss_flags = 0 + LibC.sigaltstack(pointerof(altstack), Pointer(LibC::StackT).null) + + sa_mask = uninitialized LibC::SigsetT + LibC.sigemptyset(pointerof(sa_mask)) + action.sa_mask = sa_mask + action.sa_flags = LibC::SA_ONSTACK | LibC::SA_SIGINFO + action.sa_sigaction = @@sigfault_handler + + LibC.sigaction(SEGV, pointerof(action), Pointer(LibC::Sigaction).null) + LibC.sigaction(BUS, pointerof(action), Pointer(LibC::Sigaction).null) + end end # :nodoc: