aboutsummaryrefslogtreecommitdiff
path: root/tinycc/lib
diff options
context:
space:
mode:
authorUneven Prankster <unevenprankster@protonmail.com>2023-10-15 21:28:29 -0300
committerUneven Prankster <unevenprankster@protonmail.com>2023-10-15 21:28:29 -0300
commit1c0cc775732201f4c4d3ee0d6772be786b3b4aa1 (patch)
treef5d692d046868261275c7430a624c3ea9ed75d3d /tinycc/lib
parenta89f892640cf12f75c7ce18e6e88c70a8d3965ed (diff)
A lot has certainly happened!
Diffstat (limited to 'tinycc/lib')
-rw-r--r--tinycc/lib/Makefile94
-rw-r--r--tinycc/lib/alloca-bt.S96
-rw-r--r--tinycc/lib/alloca.S85
-rw-r--r--tinycc/lib/armeabi.c544
-rw-r--r--tinycc/lib/armflush.c51
-rw-r--r--tinycc/lib/atomic.S858
-rw-r--r--tinycc/lib/bcheck.c2270
-rw-r--r--tinycc/lib/bt-dll.c74
-rw-r--r--tinycc/lib/bt-exe.c74
-rw-r--r--tinycc/lib/bt-log.c47
-rw-r--r--tinycc/lib/builtin.c164
-rw-r--r--tinycc/lib/dsohandle.c1
-rw-r--r--tinycc/lib/lib-arm64.c677
-rw-r--r--tinycc/lib/libtcc1.c641
-rw-r--r--tinycc/lib/stdatomic.c166
-rw-r--r--tinycc/lib/tcov.c428
-rw-r--r--tinycc/lib/va_list.c67
17 files changed, 0 insertions, 6337 deletions
diff --git a/tinycc/lib/Makefile b/tinycc/lib/Makefile
deleted file mode 100644
index 6f08376..0000000
--- a/tinycc/lib/Makefile
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# Tiny C Compiler Makefile for libtcc1.a
-#
-
-TOP = ..
-include $(TOP)/Makefile
-VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
-T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
-X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
-
-XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
-XCC = $(XTCC)
-XAR = $(XTCC) -ar
-XFLAGS-unx = -B$(TOPSRC)
-XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
-XFLAGS = $(XFLAGS$(XCFG)) -I$(TOP)
-XCFG = $(or $(findstring -win,$T),-unx)
-S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
-
-# in order to use gcc, type: make <target>-libtcc1-usegcc=yes
-arm-libtcc1-usegcc ?= no
-
-# This makes bounds checking 40%..60% faster.
-x86_64-libtcc1-usegcc=yes
-#i386-libtcc1-usegcc=yes
-
-ifeq "$($(T)-libtcc1-usegcc)" "yes"
- XCC = $(CC)
- XAR = $(AR)
- XFLAGS = $(CFLAGS) -fPIC -gdwarf -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable
-endif
-
-ifneq ($(CONFIG_backtrace),no)
-# only for native compiler
-ifneq ($(CONFIG_bcheck),no)
-$(X)BCHECK_O = bcheck.o
-endif
-$(X)BT_O = bt-exe.o bt-log.o
-$(X)B_O = $(BCHECK_O) bt-exe.o bt-log.o bt-dll.o
-endif
-$(X)BT_O += tcov.o
-
-DSO_O = dsohandle.o
-
-I386_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
-X86_64_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O)
-ARM_O = libtcc1.o armeabi.o alloca.o armflush.o stdatomic.o atomic.o builtin.o $(BT_O)
-ARM64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O)
-RISCV64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O)
-WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
-
-OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O)
-OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) $(DSO_O)
-OBJ-x86_64-osx = $(X86_64_O) va_list.o $(BCHECK_O)
-OBJ-i386-win32 = $(I386_O) chkstk.o $(B_O) $(WIN_O)
-OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(B_O) $(WIN_O)
-OBJ-arm64 = $(ARM64_O) $(BCHECK_O) $(DSO_O)
-OBJ-arm64-osx = $(ARM64_O) $(BCHECK_O)
-OBJ-arm = $(ARM_O) $(BCHECK_O) $(DSO_O)
-OBJ-arm-fpa = $(ARM_O) $(DSO_O)
-OBJ-arm-fpa-ld = $(ARM_O) $(DSO_O)
-OBJ-arm-vfp = $(ARM_O) $(DSO_O)
-OBJ-arm-eabi = $(ARM_O) $(DSO_O)
-OBJ-arm-eabihf = $(ARM_O) $(DSO_O)
-OBJ-arm-wince = $(ARM_O) $(WIN_O)
-OBJ-riscv64 = $(RISCV64_O) $(BCHECK_O) $(DSO_O)
-
-OBJ-extra = $(filter $(B_O),$(OBJ-$T))
-OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
-
-ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))
-
-all: $(ALL)
-
-$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1)
- $S$(XAR) rcs $@ $^
-
-$(X)%.o : %.c
- $S$(XCC) -c $< -o $@ $(XFLAGS)
-
-$(X)%.o : %.S
- $S$(XCC) -c $< -o $@ $(XFLAGS)
-
-$(TOP)/%.o : %.c
- $S$(XCC) -c $< -o $@ $(XFLAGS)
-
-$(TOP)/bcheck.o : XFLAGS += -g $(if $(CONFIG_musl),-DTCC_MUSL)
-$(TOP)/bt-exe.o : $(TOP)/tccrun.c
-
-$(X)crt1w.o : crt1.c
-$(X)wincrt1w.o : wincrt1.c
-
-clean :
- rm -f *.a *.o $(ALL)
diff --git a/tinycc/lib/alloca-bt.S b/tinycc/lib/alloca-bt.S
deleted file mode 100644
index c161488..0000000
--- a/tinycc/lib/alloca-bt.S
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ---------------------------------------------- */
-/* alloca-bt.S */
-
-#ifdef __leading_underscore
-# define _(s) _##s
-#else
-# define _(s) s
-#endif
-
-/* ---------------------------------------------- */
-#if defined __i386__
-
-.globl _(__bound_alloca)
-_(__bound_alloca):
- pop %edx
- pop %eax
- mov %eax, %ecx
- add $3+1,%eax
- and $-4,%eax
- jz p6
-
-#ifdef _WIN32
-p4:
- cmp $4096,%eax
- jbe p5
- test %eax,-4096(%esp)
- sub $4096,%esp
- sub $4096,%eax
- jmp p4
-
-p5:
-#endif
-
- sub %eax,%esp
- mov %esp,%eax
-
- push %edx
- push %eax
- push %ecx
- push %eax
- call _(__bound_new_region)
- add $8, %esp
- pop %eax
- pop %edx
-
-p6:
- push %edx
- push %edx
- ret
-
-/* ---------------------------------------------- */
-#elif defined __x86_64__
-
-.globl _(__bound_alloca)
-_(__bound_alloca):
-#ifdef _WIN32
- inc %rcx # add one extra to separate regions
- jmp _(alloca)
-.globl _(__bound_alloca_nr)
-_(__bound_alloca_nr):
- dec %rcx
- push %rax
- mov %rcx,%rdx
- mov %rax,%rcx
- sub $32,%rsp
- call _(__bound_new_region)
- add $32,%rsp
- pop %rax
- ret
-#else
- pop %rdx
- mov %rdi,%rax
- mov %rax,%rsi # size, a second parm to the __bound_new_region
-
- add $15 + 1,%rax # add one extra to separate regions
- and $-16,%rax
- jz p3
-
-
- sub %rax,%rsp
- mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
- mov %rsp,%rax
-
- push %rdx
- push %rax
- call _(__bound_new_region)
- pop %rax
- pop %rdx
-
-p3:
- push %rdx
- ret
-#endif
-
-/* ---------------------------------------------- */
-#endif
diff --git a/tinycc/lib/alloca.S b/tinycc/lib/alloca.S
deleted file mode 100644
index 6ebafd7..0000000
--- a/tinycc/lib/alloca.S
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ---------------------------------------------- */
-/* alloca.S */
-
-#ifdef __leading_underscore
-# define _(s) _##s
-#else
-# define _(s) s
-#endif
-
-/* ---------------------------------------------- */
-#if defined __i386__
-
-.globl _(alloca), _(__alloca)
-_(alloca):
-_(__alloca):
- push %ebp
- mov %esp,%ebp
- mov 8(%ebp),%eax
- add $3,%eax
- and $-4,%eax
-#ifdef _WIN32
- jmp .+16 #p2
-p1:
- sub $4096,%esp
- sub $4096,%eax
- test %eax,(%esp)
-p2:
- cmp $4096,%eax
- jae p1
-#endif
- sub %eax,%esp
- mov 4(%ebp),%eax
- mov 0(%ebp),%ebp
- add $8,%esp
- push %eax
- lea 8(%esp),%eax
- ret
-
-/* ---------------------------------------------- */
-#elif defined __x86_64__
-
-.globl _(alloca)
-_(alloca):
- pop %rdx
-#ifdef _WIN32
- mov %rcx,%rax
-#else
- mov %rdi,%rax
-#endif
- add $15,%rax
- and $-16,%rax
- jz p3
-
-#ifdef _WIN32
-p1:
- cmp $4096,%rax
- jbe p2
- test %rax,-4096(%rsp)
- sub $4096,%rsp
- sub $4096,%rax
- jmp p1
-p2:
-#endif
- sub %rax,%rsp
- mov %rsp,%rax
-p3:
- push %rdx
- ret
-
-/* ---------------------------------------------- */
-#elif defined __arm__
-
- .text
- .align 2
- .global alloca
- .type alloca, %function
-alloca:
- rsb sp, r0, sp
- bic sp, sp, #7
- mov r0, sp
- mov pc, lr
- .size alloca, .-alloca
-
-/* ---------------------------------------------- */
-#endif
diff --git a/tinycc/lib/armeabi.c b/tinycc/lib/armeabi.c
deleted file mode 100644
index 6ade65e..0000000
--- a/tinycc/lib/armeabi.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/* TCC ARM runtime EABI
- Copyright (C) 2013 Thomas Preud'homme
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.*/
-
-#ifdef __TINYC__
-#define INT_MIN (-2147483647 - 1)
-#define INT_MAX 2147483647
-#define UINT_MAX 0xffffffff
-#define LONG_MIN (-2147483647L - 1)
-#define LONG_MAX 2147483647L
-#define ULONG_MAX 0xffffffffUL
-#define LLONG_MAX 9223372036854775807LL
-#define LLONG_MIN (-9223372036854775807LL - 1)
-#define ULLONG_MAX 0xffffffffffffffffULL
-#else
-#include <limits.h>
-#endif
-
-/* We rely on the little endianness and EABI calling convention for this to
- work */
-
-typedef struct double_unsigned_struct {
- unsigned low;
- unsigned high;
-} double_unsigned_struct;
-
-typedef struct unsigned_int_struct {
- unsigned low;
- int high;
-} unsigned_int_struct;
-
-#define REGS_RETURN(name, type) \
- void name ## _return(type ret) {}
-
-
-/* Float helper functions */
-
-#define FLOAT_EXP_BITS 8
-#define FLOAT_FRAC_BITS 23
-
-#define DOUBLE_EXP_BITS 11
-#define DOUBLE_FRAC_BITS 52
-
-#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
-
-REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
-REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
-
-/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
-
-
-/* float to [unsigned] long long conversion */
-#define DEFINE__AEABI_F2XLZ(name, with_sign) \
-void __aeabi_ ## name(unsigned val) \
-{ \
- int exp, high_shift, sign; \
- double_unsigned_struct ret; \
- \
- /* compute sign */ \
- sign = val >> 31; \
- \
- /* compute real exponent */ \
- exp = val >> FLOAT_FRAC_BITS; \
- exp &= (1 << FLOAT_EXP_BITS) - 1; \
- exp -= ONE_EXP(FLOAT); \
- \
- /* undefined behavior if truncated value cannot be represented */ \
- if (with_sign) { \
- if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
- return; \
- } else { \
- if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
- return; \
- } \
- \
- val &= (1 << FLOAT_FRAC_BITS) - 1; \
- if (exp >= 32) { \
- ret.high = 1 << (exp - 32); \
- if (exp - 32 >= FLOAT_FRAC_BITS) { \
- ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \
- ret.low = 0; \
- } else { \
- high_shift = FLOAT_FRAC_BITS - (exp - 32); \
- ret.high |= val >> high_shift; \
- ret.low = val << (32 - high_shift); \
- } \
- } else { \
- ret.high = 0; \
- ret.low = 1 << exp; \
- if (exp > FLOAT_FRAC_BITS) \
- ret.low |= val << (exp - FLOAT_FRAC_BITS); \
- else \
- ret.low |= val >> (FLOAT_FRAC_BITS - exp); \
- } \
- \
- /* encode negative integer using 2's complement */ \
- if (with_sign && sign) { \
- ret.low = ~ret.low; \
- ret.high = ~ret.high; \
- if (ret.low == UINT_MAX) { \
- ret.low = 0; \
- ret.high++; \
- } else \
- ret.low++; \
- } \
- \
- double_unsigned_struct_return(ret); \
-}
-
-/* float to unsigned long long conversion */
-DEFINE__AEABI_F2XLZ(f2ulz, 0)
-
-/* float to long long conversion */
-DEFINE__AEABI_F2XLZ(f2lz, 1)
-
-/* double to [unsigned] long long conversion */
-#define DEFINE__AEABI_D2XLZ(name, with_sign) \
-void __aeabi_ ## name(double_unsigned_struct val) \
-{ \
- int exp, high_shift, sign; \
- double_unsigned_struct ret; \
- \
- if ((val.high & ~0x80000000) == 0 && val.low == 0) { \
- ret.low = ret.high = 0; \
- goto _ret_; \
- } \
- \
- /* compute sign */ \
- sign = val.high >> 31; \
- \
- /* compute real exponent */ \
- exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \
- exp &= (1 << DOUBLE_EXP_BITS) - 1; \
- exp -= ONE_EXP(DOUBLE); \
- \
- /* undefined behavior if truncated value cannot be represented */ \
- if (with_sign) { \
- if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
- return; \
- } else { \
- if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
- return; \
- } \
- \
- val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \
- if (exp >= 32) { \
- ret.high = 1 << (exp - 32); \
- if (exp >= DOUBLE_FRAC_BITS) { \
- high_shift = exp - DOUBLE_FRAC_BITS; \
- ret.high |= val.high << high_shift; \
- ret.high |= val.low >> (32 - high_shift); \
- ret.low = val.low << high_shift; \
- } else { \
- high_shift = DOUBLE_FRAC_BITS - exp; \
- ret.high |= val.high >> high_shift; \
- ret.low = val.high << (32 - high_shift); \
- ret.low |= val.low >> high_shift; \
- } \
- } else { \
- ret.high = 0; \
- ret.low = 1 << exp; \
- if (exp > DOUBLE_FRAC_BITS - 32) { \
- high_shift = exp - DOUBLE_FRAC_BITS - 32; \
- ret.low |= val.high << high_shift; \
- ret.low |= val.low >> (32 - high_shift); \
- } else \
- ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \
- } \
- \
- /* encode negative integer using 2's complement */ \
- if (with_sign && sign) { \
- ret.low = ~ret.low; \
- ret.high = ~ret.high; \
- if (ret.low == UINT_MAX) { \
- ret.low = 0; \
- ret.high++; \
- } else \
- ret.low++; \
- } \
- \
-_ret_: \
- double_unsigned_struct_return(ret); \
-}
-
-/* double to unsigned long long conversion */
-DEFINE__AEABI_D2XLZ(d2ulz, 0)
-
-/* double to long long conversion */
-DEFINE__AEABI_D2XLZ(d2lz, 1)
-
-/* long long to float conversion */
-#define DEFINE__AEABI_XL2F(name, with_sign) \
-unsigned __aeabi_ ## name(unsigned long long v) \
-{ \
- int s /* shift */, flb /* first lost bit */, sign = 0; \
- unsigned p = 0 /* power */, ret; \
- double_unsigned_struct val; \
- \
- /* fraction in negative float is encoded in 1's complement */ \
- if (with_sign && (v & (1ULL << 63))) { \
- sign = 1; \
- v = ~v + 1; \
- } \
- val.low = v; \
- val.high = v >> 32; \
- /* fill fraction bits */ \
- for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
- if (p) { \
- ret = val.high & (p - 1); \
- if (s < FLOAT_FRAC_BITS) { \
- ret <<= FLOAT_FRAC_BITS - s; \
- ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \
- flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \
- } else { \
- flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
- ret >>= s - FLOAT_FRAC_BITS; \
- } \
- s += 32; \
- } else { \
- for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
- if (p) { \
- ret = val.low & (p - 1); \
- if (s <= FLOAT_FRAC_BITS) { \
- ret <<= FLOAT_FRAC_BITS - s; \
- flb = 0; \
- } else { \
- flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
- ret >>= s - FLOAT_FRAC_BITS; \
- } \
- } else \
- return 0; \
- } \
- if (flb) \
- ret++; \
- \
- /* fill exponent bits */ \
- ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \
- \
- /* fill sign bit */ \
- ret |= sign << 31; \
- \
- return ret; \
-}
-
-/* unsigned long long to float conversion */
-DEFINE__AEABI_XL2F(ul2f, 0)
-
-/* long long to float conversion */
-DEFINE__AEABI_XL2F(l2f, 1)
-
-/* long long to double conversion */
-#define __AEABI_XL2D(name, with_sign) \
-void __aeabi_ ## name(unsigned long long v) \
-{ \
- int s /* shift */, high_shift, sign = 0; \
- unsigned tmp, p = 0; \
- double_unsigned_struct val, ret; \
- \
- /* fraction in negative float is encoded in 1's complement */ \
- if (with_sign && (v & (1ULL << 63))) { \
- sign = 1; \
- v = ~v + 1; \
- } \
- val.low = v; \
- val.high = v >> 32; \
- \
- /* fill fraction bits */ \
- for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
- if (p) { \
- tmp = val.high & (p - 1); \
- if (s < DOUBLE_FRAC_BITS - 32) { \
- high_shift = DOUBLE_FRAC_BITS - 32 - s; \
- ret.high = tmp << high_shift; \
- ret.high |= val.low >> (32 - high_shift); \
- ret.low = val.low << high_shift; \
- } else { \
- high_shift = s - (DOUBLE_FRAC_BITS - 32); \
- ret.high = tmp >> high_shift; \
- ret.low = tmp << (32 - high_shift); \
- ret.low |= val.low >> high_shift; \
- if ((val.low >> (high_shift - 1)) & 1) { \
- if (ret.low == UINT_MAX) { \
- ret.high++; \
- ret.low = 0; \
- } else \
- ret.low++; \
- } \
- } \
- s += 32; \
- } else { \
- for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
- if (p) { \
- tmp = val.low & (p - 1); \
- if (s <= DOUBLE_FRAC_BITS - 32) { \
- high_shift = DOUBLE_FRAC_BITS - 32 - s; \
- ret.high = tmp << high_shift; \
- ret.low = 0; \
- } else { \
- high_shift = s - (DOUBLE_FRAC_BITS - 32); \
- ret.high = tmp >> high_shift; \
- ret.low = tmp << (32 - high_shift); \
- } \
- } else { \
- ret.high = ret.low = 0; \
- goto _ret_; \
- } \
- } \
- \
- /* fill exponent bits */ \
- ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \
- \
- /* fill sign bit */ \
- ret.high |= sign << 31; \
- \
-_ret_: \
- double_unsigned_struct_return(ret); \
-}
-
-/* unsigned long long to double conversion */
-__AEABI_XL2D(ul2d, 0)
-
-/* long long to double conversion */
-__AEABI_XL2D(l2d, 1)
-
-
-/* Long long helper functions */
-
-/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
-
-#define define_aeabi_xdivmod_signed_type(basetype, type) \
-typedef struct type { \
- basetype quot; \
- unsigned basetype rem; \
-} type
-
-#define define_aeabi_xdivmod_unsigned_type(basetype, type) \
-typedef struct type { \
- basetype quot; \
- basetype rem; \
-} type
-
-#define AEABI_UXDIVMOD(name,type, rettype, typemacro) \
-static inline rettype aeabi_ ## name (type num, type den) \
-{ \
- rettype ret; \
- type quot = 0; \
- \
- /* Increase quotient while it is less than numerator */ \
- while (num >= den) { \
- type q = 1; \
- \
- /* Find closest power of two */ \
- while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
- q <<= 1; \
- \
- /* Compute difference between current quotient and numerator */ \
- num -= q * den; \
- quot += q; \
- } \
- ret.quot = quot; \
- ret.rem = num; \
- return ret; \
-}
-
-#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \
-void __aeabi_ ## name(type numerator, type denominator) \
-{ \
- unsigned type num, den; \
- urettype uxdiv_ret; \
- rettype ret; \
- \
- if (numerator >= 0) \
- num = numerator; \
- else \
- num = 0 - numerator; \
- if (denominator >= 0) \
- den = denominator; \
- else \
- den = 0 - denominator; \
- uxdiv_ret = aeabi_ ## uiname(num, den); \
- /* signs differ */ \
- if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
- ret.quot = 0 - uxdiv_ret.quot; \
- else \
- ret.quot = uxdiv_ret.quot; \
- if (numerator < 0) \
- ret.rem = 0 - uxdiv_ret.rem; \
- else \
- ret.rem = uxdiv_ret.rem; \
- \
- rettype ## _return(ret); \
-}
-
-define_aeabi_xdivmod_signed_type(long long, lldiv_t);
-define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
-define_aeabi_xdivmod_signed_type(int, idiv_t);
-define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
-
-REGS_RETURN(lldiv_t, lldiv_t)
-REGS_RETURN(ulldiv_t, ulldiv_t)
-REGS_RETURN(idiv_t, idiv_t)
-REGS_RETURN(uidiv_t, uidiv_t)
-
-AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
-
-__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
-
-void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
-{
- ulldiv_t_return(aeabi_uldivmod(num, den));
-}
-
-void __aeabi_llsl(double_unsigned_struct val, int shift)
-{
- double_unsigned_struct ret;
-
- if (shift >= 32) {
- val.high = val.low;
- val.low = 0;
- shift -= 32;
- }
- if (shift > 0) {
- ret.low = val.low << shift;
- ret.high = (val.high << shift) | (val.low >> (32 - shift));
- double_unsigned_struct_return(ret);
- return;
- }
- double_unsigned_struct_return(val);
-}
-
-#define aeabi_lsr(val, shift, fill, type) \
- type ## _struct ret; \
- \
- if (shift >= 32) { \
- val.low = val.high; \
- val.high = fill; \
- shift -= 32; \
- } \
- if (shift > 0) { \
- ret.high = val.high >> shift; \
- ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
- type ## _struct_return(ret); \
- return; \
- } \
- type ## _struct_return(val);
-
-void __aeabi_llsr(double_unsigned_struct val, int shift)
-{
- aeabi_lsr(val, shift, 0, double_unsigned);
-}
-
-void __aeabi_lasr(unsigned_int_struct val, int shift)
-{
- aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
-}
-
-
-/* Integer division functions */
-
-AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
-
-int __aeabi_idiv(int numerator, int denominator)
-{
- unsigned num, den;
- uidiv_t ret;
-
- if (numerator >= 0)
- num = numerator;
- else
- num = 0 - numerator;
- if (denominator >= 0)
- den = denominator;
- else
- den = 0 - denominator;
- ret = aeabi_uidivmod(num, den);
- if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
- ret.quot *= -1;
- return ret.quot;
-}
-
-unsigned __aeabi_uidiv(unsigned num, unsigned den)
-{
- return aeabi_uidivmod(num, den).quot;
-}
-
-__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
-
-void __aeabi_uidivmod(unsigned num, unsigned den)
-{
- uidiv_t_return(aeabi_uidivmod(num, den));
-}
-
-/* Some targets do not have all eabi calls (OpenBSD) */
-typedef __SIZE_TYPE__ size_t;
-extern void *memcpy(void *dest, const void *src, size_t n);
-extern void *memmove(void *dest, const void *src, size_t n);
-extern void *memset(void *s, int c, size_t n);
-
-void *
-__aeabi_memcpy (void *dest, const void *src, size_t n)
-{
- return memcpy (dest, src, n);
-}
-
-void *
-__aeabi_memmove (void *dest, const void *src, size_t n)
-{
- return memmove (dest, src, n);
-}
-
-void *
-__aeabi_memmove4 (void *dest, const void *src, size_t n)
-{
- return memmove (dest, src, n);
-}
-
-void *
-__aeabi_memmove8 (void *dest, const void *src, size_t n)
-{
- return memmove (dest, src, n);
-}
-
-void *
-__aeabi_memset (void *s, size_t n, int c)
-{
- return memset (s, c, n);
-}
diff --git a/tinycc/lib/armflush.c b/tinycc/lib/armflush.c
deleted file mode 100644
index c379e43..0000000
--- a/tinycc/lib/armflush.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* armflush.c - flush the instruction cache
-
- __clear_cache is used in tccrun.c, It is a built-in
- intrinsic with gcc. However tcc in order to compile
- itself needs this function */
-
-#ifdef __TINYC__
-
-/* syscall wrapper */
-unsigned _tccsyscall(unsigned syscall_nr, ...);
-
-/* arm-tcc supports only fake asm currently */
-__asm__(
- ".global _tccsyscall\n"
- "_tccsyscall:\n"
- "push {r7, lr}\n\t"
- "mov r7, r0\n\t"
- "mov r0, r1\n\t"
- "mov r1, r2\n\t"
- "mov r2, r3\n\t"
- "svc #0\n\t"
- "pop {r7, pc}"
- );
-
-/* from unistd.h: */
-#if defined(__thumb__) || defined(__ARM_EABI__)
-# define __NR_SYSCALL_BASE 0x0
-#else
-# define __NR_SYSCALL_BASE 0x900000
-#endif
-#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
-#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
-
-#define syscall _tccsyscall
-
-#else
-
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <stdio.h>
-
-#endif
-
-/* Flushing for tccrun */
-void __clear_cache(void *beginning, void *end)
-{
-/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
- * However, there is no ARM asm parser in tcc so we use it for now */
- syscall(__ARM_NR_cacheflush, beginning, end, 0);
-}
diff --git a/tinycc/lib/atomic.S b/tinycc/lib/atomic.S
deleted file mode 100644
index 29fdbee..0000000
--- a/tinycc/lib/atomic.S
+++ /dev/null
@@ -1,858 +0,0 @@
-/* ---------------------------------------------- */
-/* This file implements for arm/arm64/riscv:
- * __atomic_compare_exchange_1
- * __atomic_compare_exchange_2
- * __atomic_compare_exchange_4
- * __atomic_compare_exchange_8
- */
-
-#ifdef __leading_underscore
-# define _(s) _##s
-#else
-# define _(s) s
-#endif
-
-#if defined __i386__
- .text
- .align 2
-
- .global _(__atomic_test_and_set)
- .type _(__atomic_test_and_set), %function
-_(__atomic_test_and_set):
- movl 4(%esp), %edx
- movl $1, %eax
- xchgb (%edx), %al
- ret
- .size _(__atomic_test_and_set), .-_(__atomic_test_and_set)
-
- .global _(__atomic_clear)
- .type _(__atomic_clear), %function
-_(__atomic_clear):
- movl 4(%esp), %edx
- xorl %eax, %eax
- xchgb (%edx), %al
- ret
- .size _(__atomic_clear), .-_(__atomic_clear)
-
-#elif defined __x86_64__
- .text
- .align 2
-
- .global _(__atomic_test_and_set)
- .type _(__atomic_test_and_set), %function
-_(__atomic_test_and_set):
- movl $1, %eax
- xchgb (%rdi), %al
- ret
- .size _(__atomic_test_and_set), .-_(__atomic_test_and_set)
-
- .global _(__atomic_clear)
- .type _(__atomic_clear), %function
-_(__atomic_clear):
- xorl %eax, %eax
- xchgb (%rdi), %al
- ret
- .size _(__atomic_clear), .-_(__atomic_clear)
-
-#elif defined __arm__
-
-#ifndef __TINYC__
- .arch armv6k
- .syntax unified
-#endif
- .text
- .align 2
-
- .global _(fetch_and_add_arm)
- .type _(fetch_and_add_arm), %function
-_(fetch_and_add_arm):
- mcr p15, #0, r0, c7, c10, #5
-.L0:
- ldrex r3, [r0]
- add r3, r3, r1
- strex r2, r3, [r0]
- cmp r2, #0
- bne .L0
- mcr p15, #0, r0, c7, c10, #5
- bx lr
- .size _(fetch_and_add_arm), .-_(fetch_and_add_arm)
-
- .global _(__atomic_test_and_set)
- .type _(__atomic_test_and_set), %function
-_(__atomic_test_and_set):
-#ifdef __TINYC__
- .int 0xe92d4030
- .int 0xee070fba
- .int 0xe5d03000
- .int 0xe24dd014
- .int 0xe1a05000
- .int 0xe2533000
- .int 0xe1a04001
- .int 0x13a03001
- .int 0xee070fba
- .int 0xe5cd300f
- .int 0xe3a03001
- .int 0xe1a02003
- .int 0xe28d100f
- .int 0xe1a00005
- .int 0xe58d4004
- .int 0xe58d4000
- .int 0xeb000009
- .int 0xe3500000
- .int 0x0afffff6
- .int 0xe5dd000f
- .int 0xe28dd014
- .int 0xe8bd8030
-#else
- push {r4, r5, lr}
- mcr p15, 0, r0, c7, c10, 5
- ldrb r3, [r0]
- sub sp, sp, #20
- mov r5, r0
- subs r3, r3, #0
- mov r4, r1
- movne r3, #1
- mcr p15, 0, r0, c7, c10, 5
- strb r3, [sp, #15]
-.L20:
- mov r3, #1
- mov r2, r3
- add r1, sp, #15
- mov r0, r5
- str r4, [sp, #4]
- str r4, [sp]
- bl __atomic_compare_exchange_1
- cmp r0, #0
- beq .L20
- ldrb r0, [sp, #15]
- add sp, sp, #20
- pop {r4, r5, pc}
-#endif
- .size _(__atomic_test_and_set), .-_(__atomic_test_and_set)
-
- .global _(__atomic_clear)
- .type _(__atomic_clear), %function
-_(__atomic_clear):
-#ifdef __TINYC__
- .int 0xe3a03000
- .int 0xee070fba
- .int 0xe5c03000
- .int 0xee070fba
- .int 0xe12fff1e
-#else
- mov r3, #0
- mcr p15, 0, r0, c7, c10, 5
- strb r3, [r0]
- mcr p15, 0, r0, c7, c10, 5
- bx lr
-#endif
- .size _(__atomic_clear), .-_(__atomic_clear)
-
- .global _(__atomic_compare_exchange_1)
- .type _(__atomic_compare_exchange_1), %function
-_(__atomic_compare_exchange_1):
-#ifdef __TINYC__
- .int 0xe52de004
- .int 0xe5d13000
- .int 0xf57ff05b
- .int 0xe1d0cf9f
- .int 0xe15c0003
- .int 0x1a000002
- .int 0xe1c0ef92
- .int 0xe35e0000
- .int 0x1afffff9
- .int 0x03a00001
- .int 0x13a00000
- .int 0xf57ff05b
- .int 0x15c1c000
- .int 0xe49df004
-#else
- str lr, [sp, #-4]!
- ldrb r3, [r1]
- mcr p15, 0, r0, c7, c10, 5
-.L1:
- ldrexb ip, [r0]
- cmp ip, r3
- bne .L2
- strexb lr, r2, [r0]
- cmp lr, #0
- bne .L1
-.L2:
- mcr p15, 0, r0, c7, c10, 5
- moveq r0, #1
- movne r0, #0
- strbne ip, [r1]
- ldr pc, [sp], #4
-#endif
- .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
-
- .global _(__atomic_compare_exchange_2)
- .type _(__atomic_compare_exchange_2), %function
-_(__atomic_compare_exchange_2):
-#ifdef __TINYC__
- .int 0xe52de004
- .int 0xe1d130b0
- .int 0xf57ff05b
- .int 0xe1f0cf9f
- .int 0xe15c0003
- .int 0x1a000002
- .int 0xe1e0ef92
- .int 0xe35e0000
- .int 0x1afffff9
- .int 0x03a00001
- .int 0x13a00000
- .int 0xf57ff05b
- .int 0x11c1c0b0
- .int 0xe49df004
-#else
- str lr, [sp, #-4]!
- ldrh r3, [r1]
- mcr p15, 0, r0, c7, c10, 5
-.L3:
- ldrexh ip, [r0]
- cmp ip, r3
- bne .L4
- strexh lr, r2, [r0]
- cmp lr, #0
- bne .L3
-.L4:
- mcr p15, 0, r0, c7, c10, 5
- moveq r0, #1
- movne r0, #0
- strhne ip, [r1]
- ldr pc, [sp], #4
-#endif
- .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
-
- .global _(__atomic_compare_exchange_4)
- .type _(__atomic_compare_exchange_4), %function
-_(__atomic_compare_exchange_4):
-#ifdef __TINYC__
- .int 0xe52de004
- .int 0xe5913000
- .int 0xf57ff05b
- .int 0xe190cf9f
- .int 0xe15c0003
- .int 0x1a000002
- .int 0xe180ef92
- .int 0xe35e0000
- .int 0x1afffff9
- .int 0x03a00001
- .int 0x13a00000
- .int 0xf57ff05b
- .int 0x1581c000
- .int 0xe49df004
-#else
- str lr, [sp, #-4]!
- ldr r3, [r1]
- mcr p15, 0, r0, c7, c10, 5
-.L5:
- ldrex ip, [r0]
- cmp ip, r3
- bne .L6
- strex lr, r2, [r0]
- cmp lr, #0
- bne .L5
-.L6:
- mcr p15, 0, r0, c7, c10, 5
- moveq r0, #1
- movne r0, #0
- strne ip, [r1]
- ldr pc, [sp], #4
-#endif
- .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
-
-/* ---------------------------------------------- */
-#elif defined __aarch64__
-
- .text
- .align 2
-
- .global _(fetch_and_add_arm64)
- .type _(fetch_and_add_arm64), %function
-_(fetch_and_add_arm64):
-#ifdef __TINYC__
- .int 0x885f7c02
- .int 0x0b010042
- .int 0x8803fc02
- .int 0x35ffffa3
- .int 0xd5033bbf
- .int 0xd65f03c0
-#else
- ldxr w2, [x0]
- add w2, w2, w1
- stlxr w3, w2, [x0]
- cbnz w3, _(fetch_and_add_arm64)
- dmb ish
- ret
-#endif
- .size _(fetch_and_add_arm64), .-_(fetch_and_add_arm64)
-
- .global _(__atomic_test_and_set)
- .type _(__atomic_test_and_set), %function
-_(__atomic_test_and_set):
-#ifdef __TINYC__
- .int 0xa9bf7bfd
- .int 0xaa0003e1
- .int 0x52800020
- .int 0x910003fd
- .int 0x2a0003f0
- .int 0x085ffc20
- .int 0x0811fc30
- .int 0x35ffffd1
- .int 0xa8c17bfd
- .int 0xd65f03c0
-#else
- stp x29, x30, [sp, -16]!
- mov x1, x0
- mov w0, 1
- mov x29, sp
- mov w16, w0
-.L20:
- ldaxrb w0, [x1]
- stlxrb w17, w16, [x1]
- cbnz w17, .L20
- ldp x29, x30, [sp], 16
- ret
-#endif
- .size _(__atomic_test_and_set), .-_(__atomic_test_and_set)
-
- .global _(__atomic_clear)
- .type _(__atomic_clear), %function
-_(__atomic_clear):
-#ifdef __TINYC__
- .int 0x089ffc1f
- .int 0xd65f03c0
-#else
- stlrb wzr, [x0]
- ret
-#endif
- .size _(__atomic_clear), .-_(__atomic_clear)
-
- .global _(__atomic_compare_exchange_1)
- .type _(__atomic_compare_exchange_1), %function
-_(__atomic_compare_exchange_1):
-#ifdef __TINYC__
- .int 0xa9be7bfd
- .int 0x910003fd
- .int 0xa90153f3
- .int 0xaa0103f3
- .int 0x12001c41
- .int 0xaa0003e2
- .int 0x39400274
- .int 0x2a1403e0
- .int 0x53001c10
- .int 0x085ffc40
- .int 0x6b10001f
- .int 0x54000061
- .int 0x0811fc41
- .int 0x35ffff91
- .int 0x6b34001f
- .int 0x1a9f17e1
- .int 0x54000040
- .int 0x39000260
- .int 0x2a0103e0
- .int 0xa94153f3
- .int 0xa8c27bfd
- .int 0xd65f03c0
-#else
- stp x29, x30, [sp, -32]!
- mov x29, sp
- stp x19, x20, [sp, 16]
- mov x19, x1
- and w1, w2, 255
- mov x2, x0
- ldrb w20, [x19]
- mov w0, w20
- uxtb w16, w0
-.L1:
- ldaxrb w0, [x2]
- cmp w0, w16
- b.ne .L2
- stlxrb w17, w1, [x2]
- cbnz w17, .L1
-.L2:
- cmp w0, w20, uxtb
- cset w1, eq
- beq .L3
- strb w0, [x19]
-.L3:
- mov w0, w1
- ldp x19, x20, [sp, 16]
- ldp x29, x30, [sp], 32
- ret
-#endif
- .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
-
- .global _(__atomic_compare_exchange_2)
- .type _(__atomic_compare_exchange_2), %function
-_(__atomic_compare_exchange_2):
-#ifdef __TINYC__
- .int 0xa9be7bfd
- .int 0x910003fd
- .int 0xa90153f3
- .int 0xaa0103f3
- .int 0x12003c41
- .int 0xaa0003e2
- .int 0x79400274
- .int 0x2a1403e0
- .int 0x53003c10
- .int 0x485ffc40
- .int 0x6b10001f
- .int 0x54000061
- .int 0x4811fc41
- .int 0x35ffff91
- .int 0x6b34201f
- .int 0x1a9f17e1
- .int 0x54000040
- .int 0x79000260
- .int 0x2a0103e0
- .int 0xa94153f3
- .int 0xa8c27bfd
- .int 0xd65f03c0
-#else
- stp x29, x30, [sp, -32]!
- mov x29, sp
- stp x19, x20, [sp, 16]
- mov x19, x1
- and w1, w2, 65535
- mov x2, x0
- ldrh w20, [x19]
- mov w0, w20
- uxth w16, w0
-.L4:
- ldaxrh w0, [x2]
- cmp w0, w16
- b.ne .L5
- stlxrh w17, w1, [x2]
- cbnz w17, .L4
-.L5:
- cmp w0, w20, uxth
- cset w1, eq
- beq .L6
- strh w0, [x19]
-.L6:
- mov w0, w1
- ldp x19, x20, [sp, 16]
- ldp x29, x30, [sp], 32
- ret
-#endif
- .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
-
- .global _(__atomic_compare_exchange_4)
- .type _(__atomic_compare_exchange_4), %function
-_(__atomic_compare_exchange_4):
-#ifdef __TINYC__
- .int 0xa9be7bfd
- .int 0x910003fd
- .int 0xa90153f3
- .int 0xaa0103f3
- .int 0x2a0203e1
- .int 0xaa0003e2
- .int 0xb9400274
- .int 0x2a1403e0
- .int 0x2a0003f0
- .int 0x885ffc40
- .int 0x6b10001f
- .int 0x54000061
- .int 0x8811fc41
- .int 0x35ffff91
- .int 0x6b14001f
- .int 0x1a9f17e1
- .int 0x54000040
- .int 0xb9000260
- .int 0x2a0103e0
- .int 0xa94153f3
- .int 0xa8c27bfd
- .int 0xd65f03c0
-#else
- stp x29, x30, [sp, -32]!
- mov x29, sp
- stp x19, x20, [sp, 16]
- mov x19, x1
- mov w1, w2
- mov x2, x0
- ldr w20, [x19]
- mov w0, w20
- mov w16, w0
-.L7:
- ldaxr w0, [x2]
- cmp w0, w16
- b.ne .L8
- stlxr w17, w1, [x2]
- cbnz w17, .L7
-.L8:
- cmp w0, w20
- cset w1, eq
- beq .L9
- str w0, [x19]
-.L9:
- mov w0, w1
- ldp x19, x20, [sp, 16]
- ldp x29, x30, [sp], 32
- ret
-#endif
- .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
-
- .global _(__atomic_compare_exchange_8)
- .type _(__atomic_compare_exchange_8), %function
-_(__atomic_compare_exchange_8):
-#ifdef __TINYC__
- .int 0xa9be7bfd
- .int 0x910003fd
- .int 0xa90153f3
- .int 0xaa0103f3
- .int 0xaa0203e1
- .int 0xaa0003e2
- .int 0xf9400274
- .int 0xaa1403e0
- .int 0xaa0003f0
- .int 0xc85ffc40
- .int 0xeb10001f
- .int 0x54000061
- .int 0xc811fc41
- .int 0x35ffff91
- .int 0xeb14001f
- .int 0x1a9f17e1
- .int 0x54000040
- .int 0xf9000260
- .int 0x2a0103e0
- .int 0xa94153f3
- .int 0xa8c27bfd
- .int 0xd65f03c0
-#else
- stp x29, x30, [sp, -32]!
- mov x29, sp
- stp x19, x20, [sp, 16]
- mov x19, x1
- mov x1, x2
- mov x2, x0
- ldr x20, [x19]
- mov x0, x20
- mov x16, x0
-.L10:
- ldaxr x0, [x2]
- cmp x0, x16
- b.ne .L11
- stlxr w17, x1, [x2]
- cbnz w17, .L10
-.L11:
- cmp x0, x20
- cset w1, eq
- beq .L12
- str x0, [x19]
-.L12:
- mov w0, w1
- ldp x19, x20, [sp, 16]
- ldp x29, x30, [sp], 32
- ret
-#endif
- .size _(__atomic_compare_exchange_8), .-_(__atomic_compare_exchange_8)
-
-/* ---------------------------------------------- */
-#elif defined __riscv
-
- .text
- .align 2
-
- .global _(fetch_and_add_riscv64)
- .type _(fetch_and_add_riscv64), %function
-_(fetch_and_add_riscv64):
-#ifdef __TINYC__
- .int 0x0f50000f
- .int 0x004b5202f
- .short 0x8082
-#else
- fence iorw,ow
- amoadd.w.aq zero,a1,0(a0)
- ret
-#endif
- .size _(fetch_and_add_riscv64), .-_(fetch_and_add_riscv64)
-
- .global _(__atomic_test_and_set)
- .type _(__atomic_test_and_set), %function
-_(__atomic_test_and_set):
-#ifdef __TINYC__
- .int 0x00357793
- .int 0x0037979b
- .short 0x4685
- .short 0x9971
- .int 0x00f696bb
- .int 0x0f50000f
- .int 0x44d5272f
- .int 0x00f7553b
- .int 0x0ff57513
- .short 0x8082
-#else
- andi a5,a0,3
- slliw a5,a5,3
- li a3,1
- andi a0,a0,-4
- sllw a3,a3,a5
- fence iorw,ow; amoor.w.aq a4,a3,0(a0)
- srlw a0,a4,a5
- andi a0,a0,0xff
- ret
-#endif
- .size _(__atomic_test_and_set), .-_(__atomic_test_and_set)
-
- .global _(__atomic_clear)
- .type _(__atomic_clear), %function
-_(__atomic_clear):
-#ifdef __TINYC__
- .int 0x0ff0000f
- .int 0x00050023
- .int 0x0ff0000f
- .short 0x8082
-#else
- fence iorw,iorw
- sb zero,0(a0)
- fence iorw,iorw
- ret
-#endif
- .size _(__atomic_clear), .-_(__atomic_clear)
-
- .global _(__atomic_compare_exchange_1)
- .type _(__atomic_compare_exchange_1), %function
-_(__atomic_compare_exchange_1):
-#ifdef __TINYC__
- .short 0x1141
- .short 0x86ba
- .short 0x873e
- .short 0xe406
- .int 0x0ff0000f
- .int 0x0005c803
- .int 0xff857893
- .int 0x0008b783
- .short 0x891d
- .short 0x050e
- .int 0x0ff00693
- .int 0x00a696b3
- .int 0x00a81833
- .int 0x00a61633
- .int 0xfff6c713
- .short 0x8f7d
- .int 0x00f6f333
- .short 0x8f51
- .int 0x03031263
- .int 0x1008b32f
- .int 0x00f31663
- .int 0x18e8be2f
- .int 0xfe0e1ae3
- .int 0x40f30733
- .short 0x879a
- .short 0xff69
- .int 0x0ff0000f
- .short 0x4505
- .short 0xa801
- .int 0x00a7d7b3
- .int 0x00f58023
- .int 0x0ff0000f
- .short 0x4501
- .short 0x60a2
- .short 0x0141
- .short 0x8082
-#else
- addi sp,sp,-16
- mv a3,a4
- mv a4,a5
- sd ra,8(sp)
- fence
- lbu a6,0(a1)
- andi a7,a0,-8
- ld a5,0(a7)
- andi a0,a0,7
- slli a0,a0,0x3
- li a3,255
- sll a3,a3,a0
- sll a6,a6,a0
- sll a2,a2,a0
-.L1:
- not a4,a3
- and a4,a4,a5
- and t1,a3,a5
- or a4,a4,a2
- bne t1,a6,.L4
-.L2:
- lr.d t1,(a7)
- bne t1,a5,.L3
- sc.d t3,a4,(a7)
- bnez t3,.L2
-.L3:
- sub a4,t1,a5
- mv a5,t1
- bnez a4,.L1
- fence
- li a0,1
- j .L5
-.L4:
- srl a5,a5,a0
- sb a5,0(a1)
- fence
- li a0,0
-.L5:
- ld ra,8(sp)
- addi sp,sp,16
- jr ra
-#endif
- .size _(__atomic_compare_exchange_1), .-_(__atomic_compare_exchange_1)
-
- .global _(__atomic_compare_exchange_2)
- .type _(__atomic_compare_exchange_2), %function
-_(__atomic_compare_exchange_2):
-#ifdef __TINYC__
- .short 0x1141
- .short 0x86ba
- .short 0x873e
- .short 0xe406
- .int 0x0ff0000f
- .int 0x0005d803
- .int 0xff857893
- .short 0x67c1
- .short 0x891d
- .int 0x0008b703
- .short 0x050e
- .short 0x17fd
- .int 0x00a797b3
- .int 0x00a81833
- .int 0x00a61633
- .int 0xfff7c693
- .short 0x8ef9
- .int 0x00e7f333
- .short 0x8ed1
- .int 0x03031263
- .int 0x1008b32f
- .int 0x00e31663
- .int 0x18d8be2f
- .int 0xfe0e1ae3
- .int 0x40e306b3
- .short 0x871a
- .short 0xfee9
- .int 0x0ff0000f
- .short 0x4505
- .short 0xa801
- .int 0x00a75733
- .int 0x00e59023
- .int 0x0ff0000f
- .short 0x4501
- .short 0x60a2
- .short 0x0141
- .short 0x8082
-#else
- addi sp,sp,-16
- mv a3,a4
- mv a4,a5
- sd ra,8(sp)
- fence
- lhu a6,0(a1)
- andi a7,a0,-8
- lui a5,0x10
- andi a0,a0,7
- ld a4,0(a7)
- slli a0,a0,0x3
- addi a5,a5,-1
- sll a5,a5,a0
- sll a6,a6,a0
- sll a2,a2,a0
-.L6:
- not a3,a5
- and a3,a3,a4
- and t1,a5,a4
- or a3,a3,a2
- bne t1,a6,.L9
-.L7:
- lr.d t1,(a7)
- bne t1,a4,.L8
- sc.d t3,a3,(a7)
- bnez t3,.L7
-.L8:
- sub a3,t1,a4
- mv a4,t1
- bnez a3,.L6
- fence
- li a0,1
- j .L10
-.L9:
- srl a4,a4,a0
- sh a4,0(a1)
- fence
- li a0,0
-.L10:
- ld ra,8(sp)
- addi sp,sp,16
- jr ra
-#endif
- .size _(__atomic_compare_exchange_2), .-_(__atomic_compare_exchange_2)
-
- .global _(__atomic_compare_exchange_4)
- .type _(__atomic_compare_exchange_4), %function
-_(__atomic_compare_exchange_4):
-#ifdef __TINYC__
- .short 0x419c
- .int 0x0f50000f
- .int 0x1405272f
- .int 0x00f71663
- .int 0x1cc5282f
- .int 0xfe081ae3
- .int 0x40f707bb
- .int 0x0017b513
- .short 0xc391
- .short 0xc198
- .short 0x8905
- .short 0x8082
-#else
- lw a5,0(a1)
- fence iorw,ow;
-.L11:
- lr.w.aq a4,0(a0)
- bne a4,a5,.L12
- sc.w.aq a6,a2,0(a0)
- bnez a6,.L11
-.L12:
- subw a5,a4,a5
- seqz a0,a5
- beq a5,zero,.L13
- sw a4,0(a1)
-.L13:
- andi a0,a0,1
- ret
-#endif
- .size _(__atomic_compare_exchange_4), .-_(__atomic_compare_exchange_4)
-
- .global _(__atomic_compare_exchange_8)
- .type _(__atomic_compare_exchange_8), %function
-_(__atomic_compare_exchange_8):
-#ifdef __TINYC__
- .short 0x619c
- .int 0x0f50000f
- .int 0x1405372f
- .int 0x00f71563
- .int 0x1cc536af
- .short 0xfaf5
- .int 0x40f707b3
- .int 0x0017b513
- .short 0xc391
- .short 0xe198
- .short 0x8905
- .short 0x8082
-#else
- ld a5,0(a1)
- fence iorw,ow;
-.L14:
- lr.d.aq a4,0(a0)
- bne a4,a5,.L15
- sc.d.aq a3,a2,0(a0)
- bnez a3,.L14
-.L15:
- sub a5,a4,a5
- seqz a0,a5
- beq a5,zero,.L16
- sd a4,0(a1)
-.L16:
- andi a0,a0,1
- ret
-#endif
- .size _(__atomic_compare_exchange_8), .-_(__atomic_compare_exchange_8)
-
-/* ---------------------------------------------- */
-#endif
diff --git a/tinycc/lib/bcheck.c b/tinycc/lib/bcheck.c
deleted file mode 100644
index b8dd1c5..0000000
--- a/tinycc/lib/bcheck.c
+++ /dev/null
@@ -1,2270 +0,0 @@
-/*
- * Tiny C Memory and bounds checker
- *
- * Copyright (c) 2002 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <setjmp.h>
-
-#if !defined(__FreeBSD__) \
- && !defined(__FreeBSD_kernel__) \
- && !defined(__DragonFly__) \
- && !defined(__OpenBSD__) \
- && !defined(__APPLE__) \
- && !defined(__NetBSD__)
-#include <malloc.h>
-#endif
-
-#if !defined(_WIN32)
-#include <unistd.h>
-#include <sys/syscall.h>
-#endif
-
-#define BOUND_DEBUG (1)
-#define BOUND_STATISTIC (1)
-
-#if BOUND_DEBUG
- #define dprintf(a...) if (print_calls) fprintf(a)
-#else
- #define dprintf(a...)
-#endif
-
-#ifdef __attribute__
- /* an __attribute__ macro is defined in the system headers */
- #undef __attribute__
-#endif
-#define FASTCALL __attribute__((regparm(3)))
-
-#ifdef _WIN32
-# define DLL_EXPORT __declspec(dllexport)
-#else
-# define DLL_EXPORT
-#endif
-
-#if defined(__FreeBSD__) \
- || defined(__FreeBSD_kernel__) \
- || defined(__DragonFly__) \
- || defined(__OpenBSD__) \
- || defined(__NetBSD__) \
- || defined(__dietlibc__)
-
-#include <sys/mman.h>
-#define INIT_SEM()
-#define EXIT_SEM()
-#define WAIT_SEM()
-#define POST_SEM()
-#define TRY_SEM()
-#define HAVE_MEMALIGN (0)
-#define MALLOC_REDIR (0)
-#define HAVE_PTHREAD_CREATE (0)
-#define HAVE_CTYPE (0)
-#define HAVE_ERRNO (0)
-#define HAVE_SIGNAL (0)
-#define HAVE_SIGACTION (0)
-#define HAVE_FORK (0)
-#define HAVE_TLS_FUNC (0)
-#define HAVE_TLS_VAR (0)
-
-#elif defined(_WIN32)
-
-#include <windows.h>
-#include <signal.h>
-static CRITICAL_SECTION bounds_sem;
-#define INIT_SEM() InitializeCriticalSection(&bounds_sem)
-#define EXIT_SEM() DeleteCriticalSection(&bounds_sem)
-#define WAIT_SEM() EnterCriticalSection(&bounds_sem)
-#define POST_SEM() LeaveCriticalSection(&bounds_sem)
-#define TRY_SEM() TryEnterCriticalSection(&bounds_sem)
-#define HAVE_MEMALIGN (0)
-#define MALLOC_REDIR (0)
-#define HAVE_PTHREAD_CREATE (0)
-#define HAVE_CTYPE (0)
-#define HAVE_ERRNO (0)
-#define HAVE_SIGNAL (1)
-#define HAVE_SIGACTION (0)
-#define HAVE_FORK (0)
-#define HAVE_TLS_FUNC (1)
-#define HAVE_TLS_VAR (0)
-
-#else
-
-#define __USE_GNU /* get RTLD_NEXT */
-#include <sys/mman.h>
-#include <ctype.h>
-#include <pthread.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <signal.h>
-#ifdef __APPLE__
-#include <dispatch/dispatch.h>
-static dispatch_semaphore_t bounds_sem;
-#define INIT_SEM() bounds_sem = dispatch_semaphore_create(1)
-#define EXIT_SEM() dispatch_release(*(dispatch_object_t*)&bounds_sem)
-#define WAIT_SEM() if (use_sem) dispatch_semaphore_wait(bounds_sem, DISPATCH_TIME_FOREVER)
-#define POST_SEM() if (use_sem) dispatch_semaphore_signal(bounds_sem)
-#define TRY_SEM() if (use_sem) dispatch_semaphore_wait(bounds_sem, DISPATCH_TIME_NOW)
-#elif 0
-#include <semaphore.h>
-static sem_t bounds_sem;
-#define INIT_SEM() sem_init (&bounds_sem, 0, 1)
-#define EXIT_SEM() sem_destroy (&bounds_sem)
-#define WAIT_SEM() if (use_sem) while (sem_wait (&bounds_sem) < 0 \
- && errno == EINTR)
-#define POST_SEM() if (use_sem) sem_post (&bounds_sem)
-#define TRY_SEM() if (use_sem) while (sem_trywait (&bounds_sem) < 0 \
- && errno == EINTR)
-#elif 0
-static pthread_mutex_t bounds_mtx;
-#define INIT_SEM() pthread_mutex_init (&bounds_mtx, NULL)
-#define EXIT_SEM() pthread_mutex_destroy (&bounds_mtx)
-#define WAIT_SEM() if (use_sem) pthread_mutex_lock (&bounds_mtx)
-#define POST_SEM() if (use_sem) pthread_mutex_unlock (&bounds_mtx)
-#define TRY_SEM() if (use_sem) pthread_mutex_trylock (&bounds_mtx)
-#else
-static pthread_spinlock_t bounds_spin;
-/* about 25% faster then semaphore. */
-#define INIT_SEM() pthread_spin_init (&bounds_spin, 0)
-#define EXIT_SEM() pthread_spin_destroy (&bounds_spin)
-#define WAIT_SEM() if (use_sem) pthread_spin_lock (&bounds_spin)
-#define POST_SEM() if (use_sem) pthread_spin_unlock (&bounds_spin)
-#define TRY_SEM() if (use_sem) pthread_spin_trylock (&bounds_spin)
-#endif
-#define HAVE_MEMALIGN (1)
-#define MALLOC_REDIR (1)
-#define HAVE_PTHREAD_CREATE (1)
-#define HAVE_CTYPE (1)
-#define HAVE_ERRNO (1)
-#define HAVE_SIGNAL (1)
-#define HAVE_SIGACTION (1)
-#define HAVE_FORK (1)
-#if !defined(__APPLE__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-#define HAVE_TLS_FUNC (0)
-#define HAVE_TLS_VAR (1)
-#else
-#define HAVE_TLS_FUNC (1)
-#define HAVE_TLS_VAR (0)
-#endif
-#if defined TCC_MUSL || defined __ANDROID__
-# undef HAVE_CTYPE
-#endif
-#endif
-
-#if MALLOC_REDIR
-static void *(*malloc_redir) (size_t);
-static void *(*calloc_redir) (size_t, size_t);
-static void (*free_redir) (void *);
-static void *(*realloc_redir) (void *, size_t);
-static unsigned int pool_index;
-static unsigned char __attribute__((aligned(16))) initial_pool[256];
-#endif
-#if HAVE_MEMALIGN
-static void *(*memalign_redir) (size_t, size_t);
-#endif
-#if HAVE_PTHREAD_CREATE
-static int (*pthread_create_redir) (pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg);
-#endif
-#if HAVE_SIGNAL
-typedef void (*bound_sig)(int);
-static bound_sig (*signal_redir) (int signum, bound_sig handler);
-#endif
-#if HAVE_SIGACTION
-static int (*sigaction_redir) (int signum, const struct sigaction *act,
- struct sigaction *oldact);
-#endif
-#if HAVE_FORK
-static int (*fork_redir) (void);
-#endif
-
-#define TCC_TYPE_NONE (0)
-#define TCC_TYPE_MALLOC (1)
-#define TCC_TYPE_CALLOC (2)
-#define TCC_TYPE_REALLOC (3)
-#define TCC_TYPE_MEMALIGN (4)
-#define TCC_TYPE_STRDUP (5)
-
-/* this pointer is generated when bound check is incorrect */
-#define INVALID_POINTER ((void *)(-2))
-
-typedef struct tree_node Tree;
-struct tree_node {
- Tree * left, * right;
- size_t start;
- size_t size;
- unsigned char type;
- unsigned char is_invalid; /* true if pointers outside region are invalid */
-};
-
-typedef struct alloca_list_struct {
- size_t fp;
- void *p;
- size_t size;
- struct alloca_list_struct *next;
-} alloca_list_type;
-
-#if defined(_WIN32)
-#define BOUND_TID_TYPE DWORD
-#define BOUND_GET_TID(id) id = GetCurrentThreadId()
-#elif defined(__OpenBSD__)
-#define BOUND_TID_TYPE pid_t
-#define BOUND_GET_TID(id) id = getthrid()
-#elif defined(__FreeBSD__)
-#define BOUND_TID_TYPE pid_t
-#define BOUND_GET_TID(id) syscall (SYS_thr_self, &id)
-#elif defined(__NetBSD__)
-#define BOUND_TID_TYPE pid_t
-#define BOUND_GET_TID(id) id = syscall (SYS__lwp_self)
-#elif defined(__linux__)
-#define BOUND_TID_TYPE pid_t
-#define BOUND_GET_TID(id) id = syscall (SYS_gettid)
-#else
-#define BOUND_TID_TYPE int
-#define BOUND_GET_TID(id) id = 0
-#endif
-
-typedef struct jmp_list_struct {
- void *penv;
- size_t fp;
- size_t end_fp;
- BOUND_TID_TYPE tid;
- struct jmp_list_struct *next;
-} jmp_list_type;
-
-#define BOUND_STATISTIC_SPLAY (0)
-static Tree * splay (size_t addr, Tree *t);
-static Tree * splay_end (size_t addr, Tree *t);
-static Tree * splay_insert(size_t addr, size_t size, Tree * t);
-static Tree * splay_delete(size_t addr, Tree *t);
-void splay_printtree(Tree * t, int d);
-
-/* external interface */
-void __bounds_checking (int no_check);
-void __bound_checking_lock (void);
-void __bound_checking_unlock (void);
-void __bound_never_fatal (int no_check);
-DLL_EXPORT void * __bound_ptr_add(void *p, size_t offset);
-DLL_EXPORT void * __bound_ptr_indir1(void *p, size_t offset);
-DLL_EXPORT void * __bound_ptr_indir2(void *p, size_t offset);
-DLL_EXPORT void * __bound_ptr_indir4(void *p, size_t offset);
-DLL_EXPORT void * __bound_ptr_indir8(void *p, size_t offset);
-DLL_EXPORT void * __bound_ptr_indir12(void *p, size_t offset);
-DLL_EXPORT void * __bound_ptr_indir16(void *p, size_t offset);
-DLL_EXPORT void FASTCALL __bound_local_new(void *p1);
-DLL_EXPORT void FASTCALL __bound_local_delete(void *p1);
-void __bound_init(size_t *, int);
-void __bound_main_arg(int argc, char **argv, char **envp);
-void __bound_exit(void);
-void __bound_exit_dll(size_t *);
-#if !defined(_WIN32)
-void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd,
- off_t offset);
-int __bound_munmap (void *start, size_t size);
-DLL_EXPORT void __bound_siglongjmp(jmp_buf env, int val);
-#endif
-DLL_EXPORT void __bound_new_region(void *p, size_t size);
-DLL_EXPORT void __bound_setjmp(jmp_buf env);
-DLL_EXPORT void __bound_longjmp(jmp_buf env, int val);
-DLL_EXPORT void *__bound_memcpy(void *dst, const void *src, size_t size);
-DLL_EXPORT int __bound_memcmp(const void *s1, const void *s2, size_t size);
-DLL_EXPORT void *__bound_memmove(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__bound_memset(void *dst, int c, size_t size);
-DLL_EXPORT int __bound_strlen(const char *s);
-DLL_EXPORT char *__bound_strcpy(char *dst, const char *src);
-DLL_EXPORT char *__bound_strncpy(char *dst, const char *src, size_t n);
-DLL_EXPORT int __bound_strcmp(const char *s1, const char *s2);
-DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n);
-DLL_EXPORT char *__bound_strcat(char *dest, const char *src);
-DLL_EXPORT char *__bound_strncat(char *dest, const char *src, size_t n);
-DLL_EXPORT char *__bound_strchr(const char *string, int ch);
-DLL_EXPORT char *__bound_strrchr(const char *string, int ch);
-DLL_EXPORT char *__bound_strdup(const char *s);
-
-#if defined(__arm__) && defined(__ARM_EABI__)
-DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__bound___aeabi_memmove(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__bound___aeabi_memmove4(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__bound___aeabi_memmove8(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__bound___aeabi_memset(void *dst, int c, size_t size);
-DLL_EXPORT void *__aeabi_memcpy(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__aeabi_memmove(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__aeabi_memmove4(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__aeabi_memmove8(void *dst, const void *src, size_t size);
-DLL_EXPORT void *__aeabi_memset(void *dst, int c, size_t size);
-#endif
-
-#if MALLOC_REDIR
-#define BOUND_MALLOC(a) malloc_redir(a)
-#define BOUND_MEMALIGN(a,b) memalign_redir(a,b)
-#define BOUND_FREE(a) free_redir(a)
-#define BOUND_REALLOC(a,b) realloc_redir(a,b)
-#define BOUND_CALLOC(a,b) calloc_redir(a,b)
-#else
-#define BOUND_MALLOC(a) malloc(a)
-#define BOUND_MEMALIGN(a,b) memalign(a,b)
-#define BOUND_FREE(a) free(a)
-#define BOUND_REALLOC(a,b) realloc(a,b)
-#define BOUND_CALLOC(a,b) calloc(a,b)
-DLL_EXPORT void *__bound_malloc(size_t size, const void *caller);
-DLL_EXPORT void *__bound_memalign(size_t size, size_t align, const void *caller);
-DLL_EXPORT void __bound_free(void *ptr, const void *caller);
-DLL_EXPORT void *__bound_realloc(void *ptr, size_t size, const void *caller);
-DLL_EXPORT void *__bound_calloc(size_t nmemb, size_t size);
-#endif
-
-#define FREE_REUSE_SIZE (100)
-static unsigned int free_reuse_index;
-static void *free_reuse_list[FREE_REUSE_SIZE];
-
-static Tree *tree = NULL;
-#define TREE_REUSE (1)
-#if TREE_REUSE
-static Tree *tree_free_list;
-#endif
-static alloca_list_type *alloca_list;
-static jmp_list_type *jmp_list;
-
-static unsigned char inited;
-static unsigned char print_warn_ptr_add;
-static unsigned char print_calls;
-static unsigned char print_heap;
-static unsigned char print_statistic;
-static unsigned char no_strdup;
-static unsigned char use_sem;
-static int never_fatal;
-#if HAVE_TLS_FUNC
-#if defined(_WIN32)
-static int no_checking = 0;
-static DWORD no_checking_key;
-#define NO_CHECKING_CHECK() if (!p) { \
- p = (int *) LocalAlloc(LPTR, sizeof(int)); \
- if (!p) bound_alloc_error("tls malloc"); \
- *p = 0; \
- TlsSetValue(no_checking_key, p); \
- }
-#define NO_CHECKING_GET() ({ int *p = TlsGetValue(no_checking_key); \
- NO_CHECKING_CHECK(); \
- *p; \
- })
-#define NO_CHECKING_SET(v) { int *p = TlsGetValue(no_checking_key); \
- NO_CHECKING_CHECK(); \
- *p = v; \
- }
-#else
-static int no_checking = 0;
-static pthread_key_t no_checking_key;
-#define NO_CHECKING_CHECK() if (!p) { \
- p = (int *) BOUND_MALLOC(sizeof(int)); \
- if (!p) bound_alloc_error("tls malloc"); \
- *p = 0; \
- pthread_setspecific(no_checking_key, p); \
- }
-#define NO_CHECKING_GET() ({ int *p = pthread_getspecific(no_checking_key); \
- NO_CHECKING_CHECK(); \
- *p; \
- })
-#define NO_CHECKING_SET(v) { int *p = pthread_getspecific(no_checking_key); \
- NO_CHECKING_CHECK(); \
- *p = v; \
- }
-#endif
-#elif HAVE_TLS_VAR
-static __thread int no_checking = 0;
-#define NO_CHECKING_GET() no_checking
-#define NO_CHECKING_SET(v) no_checking = v
-#else
-static int no_checking = 0;
-#define NO_CHECKING_GET() no_checking
-#define NO_CHECKING_SET(v) no_checking = v
-#endif
-static char exec[100];
-
-#if BOUND_STATISTIC
-static unsigned long long bound_ptr_add_count;
-static unsigned long long bound_ptr_indir1_count;
-static unsigned long long bound_ptr_indir2_count;
-static unsigned long long bound_ptr_indir4_count;
-static unsigned long long bound_ptr_indir8_count;
-static unsigned long long bound_ptr_indir12_count;
-static unsigned long long bound_ptr_indir16_count;
-static unsigned long long bound_local_new_count;
-static unsigned long long bound_local_delete_count;
-static unsigned long long bound_malloc_count;
-static unsigned long long bound_calloc_count;
-static unsigned long long bound_realloc_count;
-static unsigned long long bound_free_count;
-static unsigned long long bound_memalign_count;
-static unsigned long long bound_mmap_count;
-static unsigned long long bound_munmap_count;
-static unsigned long long bound_alloca_count;
-static unsigned long long bound_setjmp_count;
-static unsigned long long bound_longjmp_count;
-static unsigned long long bound_mempcy_count;
-static unsigned long long bound_memcmp_count;
-static unsigned long long bound_memmove_count;
-static unsigned long long bound_memset_count;
-static unsigned long long bound_strlen_count;
-static unsigned long long bound_strcpy_count;
-static unsigned long long bound_strncpy_count;
-static unsigned long long bound_strcmp_count;
-static unsigned long long bound_strncmp_count;
-static unsigned long long bound_strcat_count;
-static unsigned long long bound_strncat_count;
-static unsigned long long bound_strchr_count;
-static unsigned long long bound_strrchr_count;
-static unsigned long long bound_strdup_count;
-static unsigned long long bound_not_found;
-#define INCR_COUNT(x) ++x
-#else
-#define INCR_COUNT(x)
-#endif
-#if BOUND_STATISTIC_SPLAY
-static unsigned long long bound_splay;
-static unsigned long long bound_splay_end;
-static unsigned long long bound_splay_insert;
-static unsigned long long bound_splay_delete;
-#define INCR_COUNT_SPLAY(x) ++x
-#else
-#define INCR_COUNT_SPLAY(x)
-#endif
-
-int tcc_backtrace(const char *fmt, ...);
-
-/* print a bound error message */
-#define bound_warning(...) \
- do { \
- WAIT_SEM (); \
- tcc_backtrace("^bcheck.c^BCHECK: " __VA_ARGS__); \
- POST_SEM (); \
- } while (0)
-
-#define bound_error(...) \
- do { \
- bound_warning(__VA_ARGS__); \
- if (never_fatal == 0) \
- exit(255); \
- } while (0)
-
-static void bound_alloc_error(const char *s)
-{
- fprintf(stderr,"FATAL: %s\n",s);
- exit (1);
-}
-
-static void bound_not_found_warning(const char *file, const char *function,
- void *ptr)
-{
- dprintf(stderr, "%s%s, %s(): Not found %p\n", exec, file, function, ptr);
-}
-
-static void fetch_and_add(int* variable, int value)
-{
-#if defined __i386__ || defined __x86_64__
- __asm__ volatile("lock; addl %0, %1"
- : "+r" (value), "+m" (*variable) // input+output
- : // No input-only
- : "memory"
- );
-#elif defined __arm__
- extern void fetch_and_add_arm(int* variable, int value);
- fetch_and_add_arm(variable, value);
-#elif defined __aarch64__
- extern void fetch_and_add_arm64(int* variable, int value);
- fetch_and_add_arm64(variable, value);
-#elif defined __riscv
- extern void fetch_and_add_riscv64(int* variable, int value);
- fetch_and_add_riscv64(variable, value);
-#else
- *variable += value;
-#endif
-}
-
-/* enable/disable checking. This can be used in signal handlers. */
-void __bounds_checking (int no_check)
-{
-#if HAVE_TLS_FUNC || HAVE_TLS_VAR
- NO_CHECKING_SET(NO_CHECKING_GET() + no_check);
-#else
- fetch_and_add (&no_checking, no_check);
-#endif
-}
-
-void __bound_checking_lock(void)
-{
- WAIT_SEM ();
-}
-
-void __bound_checking_unlock(void)
-{
- POST_SEM ();
-}
-
-/* enable/disable checking. This can be used in signal handlers. */
-void __bound_never_fatal (int neverfatal)
-{
- fetch_and_add (&never_fatal, neverfatal);
-}
-
-/* return '(p + offset)' for pointer arithmetic (a pointer can reach
- the end of a region in this case */
-void * __bound_ptr_add(void *p, size_t offset)
-{
- size_t addr = (size_t)p;
-
- if (NO_CHECKING_GET())
- return p + offset;
-
- dprintf(stderr, "%s, %s(): %p 0x%lx\n",
- __FILE__, __FUNCTION__, p, (unsigned long)offset);
-
- WAIT_SEM ();
- INCR_COUNT(bound_ptr_add_count);
- if (tree) {
- addr -= tree->start;
- if (addr >= tree->size) {
- addr = (size_t)p;
- tree = splay (addr, tree);
- addr -= tree->start;
- }
- if (addr >= tree->size) {
- addr = (size_t)p;
- tree = splay_end (addr, tree);
- addr -= tree->start;
- }
- if (addr <= tree->size) {
- if (tree->is_invalid || addr + offset > tree->size) {
- POST_SEM ();
- if (print_warn_ptr_add)
- bound_warning("%p is outside of the region", p + offset);
- if (never_fatal <= 0)
- return INVALID_POINTER; /* return an invalid pointer */
- return p + offset;
- }
- }
- else if (p) { /* Allow NULL + offset. offsetoff is using it. */
- INCR_COUNT(bound_not_found);
- POST_SEM ();
- bound_not_found_warning (__FILE__, __FUNCTION__, p);
- return p + offset;
- }
- }
- POST_SEM ();
- return p + offset;
-}
-
-/* return '(p + offset)' for pointer indirection (the resulting must
- be strictly inside the region */
-#define BOUND_PTR_INDIR(dsize) \
-void * __bound_ptr_indir ## dsize (void *p, size_t offset) \
-{ \
- size_t addr = (size_t)p; \
- \
- if (NO_CHECKING_GET()) \
- return p + offset; \
- \
- dprintf(stderr, "%s, %s(): %p 0x%lx\n", \
- __FILE__, __FUNCTION__, p, (unsigned long)offset); \
- WAIT_SEM (); \
- INCR_COUNT(bound_ptr_indir ## dsize ## _count); \
- if (tree) { \
- addr -= tree->start; \
- if (addr >= tree->size) { \
- addr = (size_t)p; \
- tree = splay (addr, tree); \
- addr -= tree->start; \
- } \
- if (addr >= tree->size) { \
- addr = (size_t)p; \
- tree = splay_end (addr, tree); \
- addr -= tree->start; \
- } \
- if (addr <= tree->size) { \
- if (tree->is_invalid || addr + offset + dsize > tree->size) { \
- POST_SEM (); \
- bound_warning("%p is outside of the region", p + offset); \
- if (never_fatal <= 0) \
- return INVALID_POINTER; /* return an invalid pointer */ \
- return p + offset; \
- } \
- } \
- else { \
- INCR_COUNT(bound_not_found); \
- POST_SEM (); \
- bound_not_found_warning (__FILE__, __FUNCTION__, p); \
- return p + offset; \
- } \
- } \
- POST_SEM (); \
- return p + offset; \
-}
-
-BOUND_PTR_INDIR(1)
-BOUND_PTR_INDIR(2)
-BOUND_PTR_INDIR(4)
-BOUND_PTR_INDIR(8)
-BOUND_PTR_INDIR(12)
-BOUND_PTR_INDIR(16)
-
-/* Needed when using ...libtcc1-usegcc=yes in lib/Makefile */
-#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
-/*
- * At least gcc 6.2 complains when __builtin_frame_address is used with
- * nonzero argument.
- */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-address"
-#endif
-
-/* return the frame pointer of the caller */
-#define GET_CALLER_FP(fp)\
-{\
- fp = (size_t)__builtin_frame_address(1);\
-}
-
-/* called when entering a function to add all the local regions */
-void FASTCALL __bound_local_new(void *p1)
-{
- size_t addr, fp, *p = p1;
-
- if (NO_CHECKING_GET())
- return;
- GET_CALLER_FP(fp);
- dprintf(stderr, "%s, %s(): p1=%p fp=%p\n",
- __FILE__, __FUNCTION__, p, (void *)fp);
- WAIT_SEM ();
- while ((addr = p[0])) {
- INCR_COUNT(bound_local_new_count);
- tree = splay_insert(addr + fp, p[1], tree);
- p += 2;
- }
- POST_SEM ();
-#if BOUND_DEBUG
- if (print_calls) {
- p = p1;
- while ((addr = p[0])) {
- dprintf(stderr, "%s, %s(): %p 0x%lx\n",
- __FILE__, __FUNCTION__,
- (void *) (addr + fp), (unsigned long) p[1]);
- p += 2;
- }
- }
-#endif
-}
-
-/* called when leaving a function to delete all the local regions */
-void FASTCALL __bound_local_delete(void *p1)
-{
- size_t addr, fp, *p = p1;
-
- if (NO_CHECKING_GET())
- return;
- GET_CALLER_FP(fp);
- dprintf(stderr, "%s, %s(): p1=%p fp=%p\n",
- __FILE__, __FUNCTION__, p, (void *)fp);
- WAIT_SEM ();
- while ((addr = p[0])) {
- INCR_COUNT(bound_local_delete_count);
- tree = splay_delete(addr + fp, tree);
- p += 2;
- }
- if (alloca_list) {
- alloca_list_type *last = NULL;
- alloca_list_type *cur = alloca_list;
-
- do {
- if (cur->fp == fp) {
- if (last)
- last->next = cur->next;
- else
- alloca_list = cur->next;
- tree = splay_delete ((size_t) cur->p, tree);
- dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
- __FILE__, __FUNCTION__, cur->p);
- BOUND_FREE (cur);
- cur = last ? last->next : alloca_list;
- }
- else {
- last = cur;
- cur = cur->next;
- }
- } while (cur);
- }
- if (jmp_list) {
- jmp_list_type *last = NULL;
- jmp_list_type *cur = jmp_list;
-
- do {
- if (cur->fp == fp) {
- if (last)
- last->next = cur->next;
- else
- jmp_list = cur->next;
- dprintf(stderr, "%s, %s(): remove setjmp %p\n",
- __FILE__, __FUNCTION__, cur->penv);
- BOUND_FREE (cur);
- cur = last ? last->next : jmp_list;
- }
- else {
- last = cur;
- cur = cur->next;
- }
- } while (cur);
- }
-
- POST_SEM ();
-#if BOUND_DEBUG
- if (print_calls) {
- p = p1;
- while ((addr = p[0])) {
- if (addr != 1) {
- dprintf(stderr, "%s, %s(): %p 0x%lx\n",
- __FILE__, __FUNCTION__,
- (void *) (addr + fp), (unsigned long) p[1]);
- }
- p+= 2;
- }
- }
-#endif
-}
-
-/* used by alloca */
-void __bound_new_region(void *p, size_t size)
-{
- size_t fp;
- alloca_list_type *last;
- alloca_list_type *cur;
- alloca_list_type *new;
-
- if (NO_CHECKING_GET())
- return;
-
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, p, (unsigned long)size);
- GET_CALLER_FP (fp);
- new = BOUND_MALLOC (sizeof (alloca_list_type));
- WAIT_SEM ();
- INCR_COUNT(bound_alloca_count);
- last = NULL;
- cur = alloca_list;
- while (cur) {
-#if defined(__i386__) || (defined(__arm__) && !defined(__ARM_EABI__))
- int align = 4;
-#elif defined(__arm__)
- int align = 8;
-#else
- int align = 16;
-#endif
- void *cure = (void *)((char *)cur->p + ((cur->size + align) & -align));
- void *pe = (void *)((char *)p + ((size + align) & -align));
- if (cur->fp == fp && ((cur->p <= p && cure > p) ||
- (p <= cur->p && pe > cur->p))) {
- if (last)
- last->next = cur->next;
- else
- alloca_list = cur->next;
- tree = splay_delete((size_t)cur->p, tree);
- break;
- }
- last = cur;
- cur = cur->next;
- }
- tree = splay_insert((size_t)p, size, tree);
- if (new) {
- new->fp = fp;
- new->p = p;
- new->size = size;
- new->next = alloca_list;
- alloca_list = new;
- }
- POST_SEM ();
- if (cur) {
- dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
- __FILE__, __FUNCTION__, cur->p);
- BOUND_FREE (cur);
- }
-}
-
-void __bound_setjmp(jmp_buf env)
-{
- jmp_list_type *jl;
- void *e = (void *) env;
-
- if (NO_CHECKING_GET() == 0) {
- dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
- WAIT_SEM ();
- INCR_COUNT(bound_setjmp_count);
- jl = jmp_list;
- while (jl) {
- if (jl->penv == e)
- break;
- jl = jl->next;
- }
- if (jl == NULL) {
- jl = BOUND_MALLOC (sizeof (jmp_list_type));
- if (jl) {
- jl->penv = e;
- jl->next = jmp_list;
- jmp_list = jl;
- }
- }
- if (jl) {
- size_t fp;
-
- GET_CALLER_FP (fp);
- jl->fp = fp;
- jl->end_fp = (size_t)__builtin_frame_address(0);
- BOUND_GET_TID(jl->tid);
- }
- POST_SEM ();
- }
-}
-
-static void __bound_long_jump(jmp_buf env, int val, int sig, const char *func)
-{
- jmp_list_type *jl;
- void *e;
- BOUND_TID_TYPE tid;
-
- if (NO_CHECKING_GET() == 0) {
- e = (void *)env;
- BOUND_GET_TID(tid);
- dprintf(stderr, "%s, %s(): %p\n", __FILE__, func, e);
- WAIT_SEM();
- INCR_COUNT(bound_longjmp_count);
- jl = jmp_list;
- while (jl) {
- if (jl->penv == e && jl->tid == tid) {
- size_t start_fp = (size_t)__builtin_frame_address(0);
- size_t end_fp = jl->end_fp;
- jmp_list_type *cur = jmp_list;
- jmp_list_type *last = NULL;
-
- while (cur->penv != e || cur->tid != tid) {
- if (cur->tid == tid) {
- dprintf(stderr, "%s, %s(): remove setjmp %p\n",
- __FILE__, func, cur->penv);
- if (last)
- last->next = cur->next;
- else
- jmp_list = cur->next;
- BOUND_FREE (cur);
- cur = last ? last->next : jmp_list;
- }
- else {
- last = cur;
- cur = cur->next;
- }
- }
- for (;;) {
- Tree *t = tree;
- alloca_list_type *last;
- alloca_list_type *cur;
-
- while (t && (t->start < start_fp || t->start > end_fp))
- if (t->start < start_fp)
- t = t->right;
- else
- t = t->left;
- if (t == NULL)
- break;
- last = NULL;
- cur = alloca_list;
- while (cur) {
- if ((size_t) cur->p == t->start) {
- dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
- __FILE__, func, cur->p);
- if (last)
- last->next = cur->next;
- else
- alloca_list = cur->next;
- BOUND_FREE (cur);
- break;
- }
- last = cur;
- cur = cur->next;
- }
- dprintf(stderr, "%s, %s(): delete %p\n",
- __FILE__, func, (void *) t->start);
- tree = splay_delete(t->start, tree);
- }
- break;
- }
- jl = jl->next;
- }
- POST_SEM();
- }
-#if !defined(_WIN32)
- sig ? siglongjmp(env, val) :
-#endif
- longjmp (env, val);
-}
-
-void __bound_longjmp(jmp_buf env, int val)
-{
- __bound_long_jump(env,val, 0, __FUNCTION__);
-}
-
-#if !defined(_WIN32)
-void __bound_siglongjmp(jmp_buf env, int val)
-{
- __bound_long_jump(env,val, 1, __FUNCTION__);
-}
-#endif
-
-#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-void __bound_init(size_t *p, int mode)
-{
- dprintf(stderr, "%s, %s(): start %s\n", __FILE__, __FUNCTION__,
- mode < 0 ? "lazy" : mode == 0 ? "normal use" : "for -run");
-
- if (inited) {
- WAIT_SEM();
- goto add_bounds;
- }
- inited = 1;
-
-#if HAVE_TLS_FUNC
-#if defined(_WIN32)
- no_checking_key = TlsAlloc();
- TlsSetValue(no_checking_key, &no_checking);
-#else
- pthread_key_create(&no_checking_key, NULL);
- pthread_setspecific(no_checking_key, &no_checking);
-#endif
-#endif
- NO_CHECKING_SET(1);
-
- print_warn_ptr_add = getenv ("TCC_BOUNDS_WARN_POINTER_ADD") != NULL;
- print_calls = getenv ("TCC_BOUNDS_PRINT_CALLS") != NULL;
- print_heap = getenv ("TCC_BOUNDS_PRINT_HEAP") != NULL;
- print_statistic = getenv ("TCC_BOUNDS_PRINT_STATISTIC") != NULL;
- never_fatal = getenv ("TCC_BOUNDS_NEVER_FATAL") != NULL;
-
- INIT_SEM ();
-
-#if MALLOC_REDIR
- {
- void *addr = mode > 0 ? RTLD_DEFAULT : RTLD_NEXT;
-
- /* tcc -run required RTLD_DEFAULT. Normal usage requires RTLD_NEXT,
- but using RTLD_NEXT with -run segfaults on MacOS in dyld as the
- generated code segment isn't registered with dyld and hence the
- caller image of dlsym isn't known to it */
- *(void **) (&malloc_redir) = dlsym (addr, "malloc");
- if (malloc_redir == NULL) {
- dprintf(stderr, "%s, %s(): use RTLD_DEFAULT\n",
- __FILE__, __FUNCTION__);
- addr = RTLD_DEFAULT;
- *(void **) (&malloc_redir) = dlsym (addr, "malloc");
- }
- *(void **) (&calloc_redir) = dlsym (addr, "calloc");
- *(void **) (&free_redir) = dlsym (addr, "free");
- *(void **) (&realloc_redir) = dlsym (addr, "realloc");
- *(void **) (&memalign_redir) = dlsym (addr, "memalign");
- dprintf(stderr, "%s, %s(): malloc_redir %p\n",
- __FILE__, __FUNCTION__, malloc_redir);
- dprintf(stderr, "%s, %s(): free_redir %p\n",
- __FILE__, __FUNCTION__, free_redir);
- dprintf(stderr, "%s, %s(): realloc_redir %p\n",
- __FILE__, __FUNCTION__, realloc_redir);
- dprintf(stderr, "%s, %s(): memalign_redir %p\n",
- __FILE__, __FUNCTION__, memalign_redir);
- if (malloc_redir == NULL || free_redir == NULL)
- bound_alloc_error ("Cannot redirect malloc/free");
-#if HAVE_PTHREAD_CREATE
- *(void **) (&pthread_create_redir) = dlsym (addr, "pthread_create");
- dprintf(stderr, "%s, %s(): pthread_create_redir %p\n",
- __FILE__, __FUNCTION__, pthread_create_redir);
- if (pthread_create_redir == NULL)
- bound_alloc_error ("Cannot redirect pthread_create");
-#endif
-#if HAVE_SIGNAL
- *(void **) (&signal_redir) = dlsym (addr, "signal");
- dprintf(stderr, "%s, %s(): signal_redir %p\n",
- __FILE__, __FUNCTION__, signal_redir);
- if (signal_redir == NULL)
- bound_alloc_error ("Cannot redirect signal");
-#endif
-#if HAVE_SIGACTION
- *(void **) (&sigaction_redir) = dlsym (addr, "sigaction");
- dprintf(stderr, "%s, %s(): sigaction_redir %p\n",
- __FILE__, __FUNCTION__, sigaction_redir);
- if (sigaction_redir == NULL)
- bound_alloc_error ("Cannot redirect sigaction");
-#endif
-#if HAVE_FORK
- *(void **) (&fork_redir) = dlsym (addr, "fork");
- dprintf(stderr, "%s, %s(): fork_redir %p\n",
- __FILE__, __FUNCTION__, fork_redir);
- if (fork_redir == NULL)
- bound_alloc_error ("Cannot redirect fork");
-#endif
- }
-#endif
-
-#ifdef __linux__
- {
- FILE *fp;
- unsigned char found;
- unsigned long start;
- unsigned long end;
- unsigned long ad =
- (unsigned long) __builtin_return_address(0);
- char line[1000];
-
- /* Display exec name. Usefull when a lot of code is compiled with tcc */
- fp = fopen ("/proc/self/comm", "r");
- if (fp) {
- memset (exec, 0, sizeof(exec));
- fread (exec, 1, sizeof(exec) - 2, fp);
- if (strchr(exec,'\n'))
- *strchr(exec,'\n') = '\0';
- strcat (exec, ":");
- fclose (fp);
- }
- /* check if dlopen is used (is threre a better way?) */
- found = 0;
- fp = fopen ("/proc/self/maps", "r");
- if (fp) {
- while (fgets (line, sizeof(line), fp)) {
- if (sscanf (line, "%lx-%lx", &start, &end) == 2 &&
- ad >= start && ad < end) {
- found = 1;
- break;
- }
- if (strstr (line,"[heap]"))
- break;
- }
- fclose (fp);
- }
- if (found == 0) {
- use_sem = 1;
- no_strdup = 1;
- }
- }
-#endif
-
- WAIT_SEM ();
-
-#if HAVE_CTYPE
-#ifdef __APPLE__
- tree = splay_insert((size_t) &_DefaultRuneLocale,
- sizeof (_DefaultRuneLocale), tree);
-#else
- /* XXX: Does not work if locale is changed */
- tree = splay_insert((size_t) __ctype_b_loc(),
- sizeof (unsigned short *), tree);
- tree = splay_insert((size_t) (*__ctype_b_loc() - 128),
- 384 * sizeof (unsigned short), tree);
- tree = splay_insert((size_t) __ctype_tolower_loc(),
- sizeof (__int32_t *), tree);
- tree = splay_insert((size_t) (*__ctype_tolower_loc() - 128),
- 384 * sizeof (__int32_t), tree);
- tree = splay_insert((size_t) __ctype_toupper_loc(),
- sizeof (__int32_t *), tree);
- tree = splay_insert((size_t) (*__ctype_toupper_loc() - 128),
- 384 * sizeof (__int32_t), tree);
-#endif
-#endif
-#if HAVE_ERRNO
- tree = splay_insert((size_t) (&errno), sizeof (int), tree);
-#endif
-
-add_bounds:
- if (!p)
- goto no_bounds;
-
- /* add all static bound check values */
- while (p[0] != 0) {
- tree = splay_insert(p[0], p[1], tree);
-#if BOUND_DEBUG
- if (print_calls) {
- dprintf(stderr, "%s, %s(): static var %p 0x%lx\n",
- __FILE__, __FUNCTION__,
- (void *) p[0], (unsigned long) p[1]);
- }
-#endif
- p += 2;
- }
-no_bounds:
-
- POST_SEM ();
- NO_CHECKING_SET(0);
- dprintf(stderr, "%s, %s(): end\n\n", __FILE__, __FUNCTION__);
-}
-
-void
-#if (defined(__GLIBC__) && (__GLIBC_MINOR__ >= 4)) || defined(_WIN32)
-__attribute__((constructor))
-#endif
-__bound_main_arg(int argc, char **argv, char **envp)
-{
- __bound_init (0, -1);
- if (argc && argv) {
- int i;
-
- WAIT_SEM ();
- for (i = 0; i < argc; i++)
- tree = splay_insert((size_t) argv[i], strlen (argv[i]) + 1, tree);
- tree = splay_insert((size_t) argv, (argc + 1) * sizeof(char *), tree);
- POST_SEM ();
-#if BOUND_DEBUG
- if (print_calls) {
- for (i = 0; i < argc; i++)
- dprintf(stderr, "%s, %s(): arg %p 0x%lx\n",
- __FILE__, __FUNCTION__,
- argv[i], (unsigned long)(strlen (argv[i]) + 1));
- dprintf(stderr, "%s, %s(): argv %p %d\n",
- __FILE__, __FUNCTION__, argv,
- (int)((argc + 1) * sizeof(char *)));
- }
-#endif
- }
-
- if (envp && *envp) {
- char **p = envp;
-
- WAIT_SEM ();
- while (*p) {
- tree = splay_insert((size_t) *p, strlen (*p) + 1, tree);
- ++p;
- }
- tree = splay_insert((size_t) envp, (++p - envp) * sizeof(char *), tree);
- POST_SEM ();
-#if BOUND_DEBUG
- if (print_calls) {
- p = envp;
- while (*p) {
- dprintf(stderr, "%s, %s(): env %p 0x%lx\n",
- __FILE__, __FUNCTION__,
- *p, (unsigned long)(strlen (*p) + 1));
- ++p;
- }
- dprintf(stderr, "%s, %s(): environ %p %d\n",
- __FILE__, __FUNCTION__, envp,
- (int)((++p - envp) * sizeof(char *)));
- }
-#endif
- }
-}
-
-void __attribute__((destructor)) __bound_exit(void)
-{
- int i;
- static const char * const alloc_type[] = {
- "", "malloc", "calloc", "realloc", "memalign", "strdup"
- };
-
- dprintf(stderr, "%s, %s():\n", __FILE__, __FUNCTION__);
-
- if (inited) {
-#if !defined(_WIN32) && !defined(__APPLE__) && !defined TCC_MUSL && \
- !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
- !defined(__ANDROID__)
- if (print_heap) {
- extern void __libc_freeres (void);
- __libc_freeres ();
- }
-#endif
-
- NO_CHECKING_SET(1);
-
- TRY_SEM ();
- while (alloca_list) {
- alloca_list_type *next = alloca_list->next;
-
- tree = splay_delete ((size_t) alloca_list->p, tree);
- BOUND_FREE (alloca_list);
- alloca_list = next;
- }
- while (jmp_list) {
- jmp_list_type *next = jmp_list->next;
-
- BOUND_FREE (jmp_list);
- jmp_list = next;
- }
- for (i = 0; i < FREE_REUSE_SIZE; i++) {
- if (free_reuse_list[i]) {
- tree = splay_delete ((size_t) free_reuse_list[i], tree);
- BOUND_FREE (free_reuse_list[i]);
- }
- }
- while (tree) {
- if (print_heap && tree->type != 0)
- fprintf (stderr, "%s, %s(): %s found size %lu\n",
- __FILE__, __FUNCTION__, alloc_type[tree->type],
- (unsigned long) tree->size);
- tree = splay_delete (tree->start, tree);
- }
-#if TREE_REUSE
- while (tree_free_list) {
- Tree *next = tree_free_list->left;
- BOUND_FREE (tree_free_list);
- tree_free_list = next;
- }
-#endif
- POST_SEM ();
- EXIT_SEM ();
-#if HAVE_TLS_FUNC
-#if defined(_WIN32)
- TlsFree(no_checking_key);
-#else
- pthread_key_delete(no_checking_key);
-#endif
-#endif
- inited = 0;
- if (print_statistic) {
-#if BOUND_STATISTIC
- fprintf (stderr, "bound_ptr_add_count %llu\n", bound_ptr_add_count);
- fprintf (stderr, "bound_ptr_indir1_count %llu\n", bound_ptr_indir1_count);
- fprintf (stderr, "bound_ptr_indir2_count %llu\n", bound_ptr_indir2_count);
- fprintf (stderr, "bound_ptr_indir4_count %llu\n", bound_ptr_indir4_count);
- fprintf (stderr, "bound_ptr_indir8_count %llu\n", bound_ptr_indir8_count);
- fprintf (stderr, "bound_ptr_indir12_count %llu\n", bound_ptr_indir12_count);
- fprintf (stderr, "bound_ptr_indir16_count %llu\n", bound_ptr_indir16_count);
- fprintf (stderr, "bound_local_new_count %llu\n", bound_local_new_count);
- fprintf (stderr, "bound_local_delete_count %llu\n", bound_local_delete_count);
- fprintf (stderr, "bound_malloc_count %llu\n", bound_malloc_count);
- fprintf (stderr, "bound_calloc_count %llu\n", bound_calloc_count);
- fprintf (stderr, "bound_realloc_count %llu\n", bound_realloc_count);
- fprintf (stderr, "bound_free_count %llu\n", bound_free_count);
- fprintf (stderr, "bound_memalign_count %llu\n", bound_memalign_count);
- fprintf (stderr, "bound_mmap_count %llu\n", bound_mmap_count);
- fprintf (stderr, "bound_munmap_count %llu\n", bound_munmap_count);
- fprintf (stderr, "bound_alloca_count %llu\n", bound_alloca_count);
- fprintf (stderr, "bound_setjmp_count %llu\n", bound_setjmp_count);
- fprintf (stderr, "bound_longjmp_count %llu\n", bound_longjmp_count);
- fprintf (stderr, "bound_mempcy_count %llu\n", bound_mempcy_count);
- fprintf (stderr, "bound_memcmp_count %llu\n", bound_memcmp_count);
- fprintf (stderr, "bound_memmove_count %llu\n", bound_memmove_count);
- fprintf (stderr, "bound_memset_count %llu\n", bound_memset_count);
- fprintf (stderr, "bound_strlen_count %llu\n", bound_strlen_count);
- fprintf (stderr, "bound_strcpy_count %llu\n", bound_strcpy_count);
- fprintf (stderr, "bound_strncpy_count %llu\n", bound_strncpy_count);
- fprintf (stderr, "bound_strcmp_count %llu\n", bound_strcmp_count);
- fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count);
- fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_count);
- fprintf (stderr, "bound_strncat_count %llu\n", bound_strncat_count);
- fprintf (stderr, "bound_strchr_count %llu\n", bound_strchr_count);
- fprintf (stderr, "bound_strrchr_count %llu\n", bound_strrchr_count);
- fprintf (stderr, "bound_strdup_count %llu\n", bound_strdup_count);
- fprintf (stderr, "bound_not_found %llu\n", bound_not_found);
-#endif
-#if BOUND_STATISTIC_SPLAY
- fprintf (stderr, "bound_splay %llu\n", bound_splay);
- fprintf (stderr, "bound_splay_end %llu\n", bound_splay_end);
- fprintf (stderr, "bound_splay_insert %llu\n", bound_splay_insert);
- fprintf (stderr, "bound_splay_delete %llu\n", bound_splay_delete);
-#endif
- }
- }
-}
-
-void __bound_exit_dll(size_t *p)
-{
- dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
-
- if (p) {
- WAIT_SEM ();
- while (p[0] != 0) {
- tree = splay_delete(p[0], tree);
-#if BOUND_DEBUG
- if (print_calls) {
- dprintf(stderr, "%s, %s(): remove static var %p 0x%lx\n",
- __FILE__, __FUNCTION__,
- (void *) p[0], (unsigned long) p[1]);
- }
-#endif
- p += 2;
- }
- POST_SEM ();
- }
-}
-
-#if HAVE_PTHREAD_CREATE
-typedef struct {
- void *(*start_routine) (void *);
- void *arg;
- sigset_t old_mask;
-} bound_thread_create_type;
-
-static void *bound_thread_create(void *bdata)
-{
- bound_thread_create_type *data = (bound_thread_create_type *) bdata;
- void *retval;
-#if HAVE_TLS_FUNC
- int *p = (int *) BOUND_MALLOC(sizeof(int));
-
- if (!p) bound_alloc_error("bound_thread_create malloc");
- *p = 0;
- pthread_setspecific(no_checking_key, p);
-#endif
- pthread_sigmask(SIG_SETMASK, &data->old_mask, NULL);
- retval = data->start_routine(data->arg);
-#if HAVE_TLS_FUNC
- pthread_setspecific(no_checking_key, NULL);
- BOUND_FREE (p);
-#endif
- BOUND_FREE (data);
- return retval;
-}
-
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine) (void *), void *arg)
-{
- int retval;
- bound_thread_create_type *data;
- sigset_t mask;
- sigset_t old_mask;
-
- use_sem = 1;
- dprintf (stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
- sigfillset(&mask);
- pthread_sigmask(SIG_SETMASK, &mask, &old_mask);
- data = (bound_thread_create_type *) BOUND_MALLOC(sizeof(bound_thread_create_type));
- if (!data) bound_alloc_error("bound_thread_create malloc");
- data->start_routine = start_routine;
- data->arg = arg;
- data->old_mask = old_mask;
- retval = pthread_create_redir(thread, attr, bound_thread_create, data);
- pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- return retval;
-}
-#endif
-
-#if HAVE_SIGNAL || HAVE_SIGACTION
-typedef union {
-#if HAVE_SIGNAL
- bound_sig signal_handler;
-#endif
-#if HAVE_SIGACTION
- void (*sig_handler)(int);
- void (*sig_sigaction)(int, siginfo_t *, void *);
-#endif
-} bound_sig_type;
-
-static unsigned char bound_sig_used[NSIG];
-static bound_sig_type bound_sig_data[NSIG];
-#endif
-
-#if HAVE_SIGNAL
-static void signal_handler(int sig)
-{
- __bounds_checking(1);
- bound_sig_data[sig].signal_handler(sig);
- __bounds_checking(-1);
-}
-
-bound_sig signal(int signum, bound_sig handler)
-{
- bound_sig retval;
-
- dprintf (stderr, "%s, %s() %d %p\n", __FILE__, __FUNCTION__,
- signum, handler);
- retval = signal_redir(signum, handler ? signal_handler : handler);
- if (retval != SIG_ERR) {
- if (bound_sig_used[signum])
- retval = bound_sig_data[signum].signal_handler;
- if (handler) {
- bound_sig_used[signum] = 1;
- bound_sig_data[signum].signal_handler = handler;
- }
- }
- return retval;
-}
-#endif
-
-#if HAVE_SIGACTION
-static void sig_handler(int sig)
-{
- __bounds_checking(1);
- bound_sig_data[sig].sig_handler(sig);
- __bounds_checking(-1);
-}
-
-static void sig_sigaction(int sig, siginfo_t *info, void *ucontext)
-{
- __bounds_checking(1);
- bound_sig_data[sig].sig_sigaction(sig, info, ucontext);
- __bounds_checking(-1);
-}
-
-int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
-{
- int retval;
- struct sigaction nact, oact;
-
- dprintf (stderr, "%s, %s() %d %p %p\n", __FILE__, __FUNCTION__,
- signum, act, oldact);
-
- if (sigaction_redir == NULL)
- __bound_init(0,-1);
-
- if (act) {
- nact = *act;
- if (nact.sa_flags & SA_SIGINFO)
- nact.sa_sigaction = sig_sigaction;
- else
- nact.sa_handler = sig_handler;
- retval = sigaction_redir(signum, &nact, &oact);
- }
- else
- retval = sigaction_redir(signum, act, &oact);
- if (retval >= 0) {
- if (bound_sig_used[signum]) {
- if (oact.sa_flags & SA_SIGINFO)
- oact.sa_sigaction = bound_sig_data[signum].sig_sigaction;
- else
- oact.sa_handler = bound_sig_data[signum].sig_handler;
- }
- if (oldact) {
- *oldact = oact;
- }
- if (act) {
- bound_sig_used[signum] = 1;
- if (act->sa_flags & SA_SIGINFO)
- bound_sig_data[signum].sig_sigaction = act->sa_sigaction;
- else
- bound_sig_data[signum].sig_handler = act->sa_handler;
- }
- }
- return retval;
-}
-#endif
-
-#if HAVE_FORK
-pid_t fork(void)
-{
- pid_t retval;
-
- WAIT_SEM();
- retval = (*fork_redir)();
- if (retval == 0)
- INIT_SEM();
- else
- POST_SEM();
- return retval;
-}
-#endif
-
-#if MALLOC_REDIR
-void *malloc(size_t size)
-#else
-void *__bound_malloc(size_t size, const void *caller)
-#endif
-{
- void *ptr;
-
-#if MALLOC_REDIR
- /* This will catch the first dlsym call from __bound_init */
- if (malloc_redir == NULL) {
- __bound_init (0, -1);
- if (malloc_redir == NULL) {
- ptr = &initial_pool[pool_index];
- pool_index = (pool_index + size + 15) & ~15;
- if (pool_index >= sizeof (initial_pool))
- bound_alloc_error ("initial memory pool too small");
- dprintf (stderr, "%s, %s(): initial %p, 0x%lx\n",
- __FILE__, __FUNCTION__, ptr, (unsigned long)size);
- return ptr;
- }
- }
-#endif
- /* we allocate one more byte to ensure the regions will be
- separated by at least one byte. With the glibc malloc, it may
- be in fact not necessary */
- ptr = BOUND_MALLOC (size + 1);
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, ptr, (unsigned long)size);
-
- if (inited && NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_malloc_count);
-
- if (ptr) {
- tree = splay_insert ((size_t) ptr, size ? size : size + 1, tree);
- if (tree && tree->start == (size_t) ptr)
- tree->type = TCC_TYPE_MALLOC;
- }
- POST_SEM ();
- }
- return ptr;
-}
-
-#if MALLOC_REDIR
-void *memalign(size_t size, size_t align)
-#else
-void *__bound_memalign(size_t size, size_t align, const void *caller)
-#endif
-{
- void *ptr;
-
-#if HAVE_MEMALIGN
- /* we allocate one more byte to ensure the regions will be
- separated by at least one byte. With the glibc malloc, it may
- be in fact not necessary */
- ptr = BOUND_MEMALIGN(size + 1, align);
-#else
- if (align > 4) {
- /* XXX: handle it ? */
- ptr = NULL;
- } else {
- /* we suppose that malloc aligns to at least four bytes */
- ptr = BOUND_MALLOC(size + 1);
- }
-#endif
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, ptr, (unsigned long)size);
-
- if (NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_memalign_count);
-
- if (ptr) {
- tree = splay_insert((size_t) ptr, size ? size : size + 1, tree);
- if (tree && tree->start == (size_t) ptr)
- tree->type = TCC_TYPE_MEMALIGN;
- }
- POST_SEM ();
- }
- return ptr;
-}
-
-#if MALLOC_REDIR
-void free(void *ptr)
-#else
-void __bound_free(void *ptr, const void *caller)
-#endif
-{
- size_t addr = (size_t) ptr;
- void *p;
-
- if (ptr == NULL || tree == NULL
-#if MALLOC_REDIR
- || ((unsigned char *) ptr >= &initial_pool[0] &&
- (unsigned char *) ptr < &initial_pool[sizeof(initial_pool)])
-#endif
- )
- return;
-
- dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, ptr);
-
- if (inited && NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_free_count);
- tree = splay (addr, tree);
- if (tree->start == addr) {
- if (tree->is_invalid) {
- POST_SEM ();
- bound_error("freeing invalid region");
- return;
- }
- tree->is_invalid = 1;
- memset (ptr, 0x5a, tree->size);
- p = free_reuse_list[free_reuse_index];
- free_reuse_list[free_reuse_index] = ptr;
- free_reuse_index = (free_reuse_index + 1) % FREE_REUSE_SIZE;
- if (p)
- tree = splay_delete((size_t)p, tree);
- ptr = p;
- }
- POST_SEM ();
- }
- BOUND_FREE (ptr);
-}
-
-#if MALLOC_REDIR
-void *realloc(void *ptr, size_t size)
-#else
-void *__bound_realloc(void *ptr, size_t size, const void *caller)
-#endif
-{
- void *new_ptr;
-
- if (size == 0) {
-#if MALLOC_REDIR
- free(ptr);
-#else
- __bound_free(ptr, caller);
-#endif
- return NULL;
- }
-
- new_ptr = BOUND_REALLOC (ptr, size + 1);
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, new_ptr, (unsigned long)size);
-
- if (NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_realloc_count);
-
- if (ptr)
- tree = splay_delete ((size_t) ptr, tree);
- if (new_ptr) {
- tree = splay_insert ((size_t) new_ptr, size ? size : size + 1, tree);
- if (tree && tree->start == (size_t) new_ptr)
- tree->type = TCC_TYPE_REALLOC;
- }
- POST_SEM ();
- }
- return new_ptr;
-}
-
-#if MALLOC_REDIR
-void *calloc(size_t nmemb, size_t size)
-#else
-void *__bound_calloc(size_t nmemb, size_t size)
-#endif
-{
- void *ptr;
-
- size *= nmemb;
-#if MALLOC_REDIR
- /* This will catch the first dlsym call from __bound_init */
- if (malloc_redir == NULL) {
- __bound_init (0, -1);
- if (malloc_redir == NULL) {
- ptr = &initial_pool[pool_index];
- pool_index = (pool_index + size + 15) & ~15;
- if (pool_index >= sizeof (initial_pool))
- bound_alloc_error ("initial memory pool too small");
- dprintf (stderr, "%s, %s(): initial %p, 0x%lx\n",
- __FILE__, __FUNCTION__, ptr, (unsigned long)size);
- memset (ptr, 0, size);
- return ptr;
- }
- }
-#endif
- ptr = BOUND_MALLOC(size + 1);
- dprintf (stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, ptr, (unsigned long)size);
-
- if (ptr) {
- memset (ptr, 0, size);
- if (NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_calloc_count);
- tree = splay_insert ((size_t) ptr, size ? size : size + 1, tree);
- if (tree && tree->start == (size_t) ptr)
- tree->type = TCC_TYPE_CALLOC;
- POST_SEM ();
- }
- }
- return ptr;
-}
-
-#if !defined(_WIN32)
-void *__bound_mmap (void *start, size_t size, int prot,
- int flags, int fd, off_t offset)
-{
- void *result;
-
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, start, (unsigned long)size);
- result = mmap (start, size, prot, flags, fd, offset);
- if (result && NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_mmap_count);
- tree = splay_insert((size_t)result, size, tree);
- POST_SEM ();
- }
- return result;
-}
-
-int __bound_munmap (void *start, size_t size)
-{
- int result;
-
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, start, (unsigned long)size);
- if (start && NO_CHECKING_GET() == 0) {
- WAIT_SEM ();
- INCR_COUNT(bound_munmap_count);
- tree = splay_delete ((size_t) start, tree);
- POST_SEM ();
- }
- result = munmap (start, size);
- return result;
-}
-#endif
-
-/* some useful checked functions */
-
-/* check that (p ... p + size - 1) lies inside 'p' region, if any */
-static void __bound_check(const void *p, size_t size, const char *function)
-{
- if (size != 0 && __bound_ptr_add((void *)p, size) == INVALID_POINTER) {
- bound_error("invalid pointer %p, size 0x%lx in %s",
- p, (unsigned long)size, function);
- }
-}
-
-static int check_overlap (const void *p1, size_t n1,
- const void *p2, size_t n2,
- const char *function)
-{
- const void *p1e = (const void *) ((const char *) p1 + n1);
- const void *p2e = (const void *) ((const char *) p2 + n2);
-
- if (NO_CHECKING_GET() == 0 && n1 != 0 && n2 !=0 &&
- ((p1 <= p2 && p1e > p2) || /* p1----p2====p1e----p2e */
- (p2 <= p1 && p2e > p1))) { /* p2----p1====p2e----p1e */
- bound_error("overlapping regions %p(0x%lx), %p(0x%lx) in %s",
- p1, (unsigned long)n1, p2, (unsigned long)n2, function);
- return never_fatal < 0;
- }
- return 0;
-}
-
-void *__bound_memcpy(void *dest, const void *src, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_mempcy_count);
- __bound_check(dest, n, "memcpy dest");
- __bound_check(src, n, "memcpy src");
- if (check_overlap(dest, n, src, n, "memcpy"))
- return dest;
- return memcpy(dest, src, n);
-}
-
-int __bound_memcmp(const void *s1, const void *s2, size_t n)
-{
- const unsigned char *u1 = (const unsigned char *) s1;
- const unsigned char *u2 = (const unsigned char *) s2;
- int retval = 0;
-
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, s1, s2, (unsigned long)n);
- INCR_COUNT(bound_memcmp_count);
- for (;;) {
- if ((ssize_t) --n == -1)
- break;
- else if (*u1 != *u2) {
- retval = *u1++ - *u2++;
- break;
- }
- ++u1;
- ++u2;
- }
- __bound_check(s1, (const void *)u1 - s1, "memcmp s1");
- __bound_check(s2, (const void *)u2 - s2, "memcmp s2");
- return retval;
-}
-
-void *__bound_memmove(void *dest, const void *src, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_memmove_count);
- __bound_check(dest, n, "memmove dest");
- __bound_check(src, n, "memmove src");
- return memmove(dest, src, n);
-}
-
-void *__bound_memset(void *s, int c, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %d, 0x%lx\n",
- __FILE__, __FUNCTION__, s, c, (unsigned long)n);
- INCR_COUNT(bound_memset_count);
- __bound_check(s, n, "memset");
- return memset(s, c, n);
-}
-
-#if defined(__arm__) && defined(__ARM_EABI__)
-void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_mempcy_count);
- __bound_check(dest, n, "memcpy dest");
- __bound_check(src, n, "memcpy src");
- if (check_overlap(dest, n, src, n, "memcpy"))
- return dest;
- return __aeabi_memcpy(dest, src, n);
-}
-
-void *__bound___aeabi_memmove(void *dest, const void *src, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_memmove_count);
- __bound_check(dest, n, "memmove dest");
- __bound_check(src, n, "memmove src");
- return __aeabi_memmove(dest, src, n);
-}
-
-void *__bound___aeabi_memmove4(void *dest, const void *src, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_memmove_count);
- __bound_check(dest, n, "memmove dest");
- __bound_check(src, n, "memmove src");
- return __aeabi_memmove4(dest, src, n);
-}
-
-void *__bound___aeabi_memmove8(void *dest, const void *src, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_memmove_count);
- __bound_check(dest, n, "memmove dest");
- __bound_check(src, n, "memmove src");
- return __aeabi_memmove8(dest, src, n);
-}
-
-void *__bound___aeabi_memset(void *s, int c, size_t n)
-{
- dprintf(stderr, "%s, %s(): %p, %d, 0x%lx\n",
- __FILE__, __FUNCTION__, s, c, (unsigned long)n);
- INCR_COUNT(bound_memset_count);
- __bound_check(s, n, "memset");
- return __aeabi_memset(s, c, n);
-}
-#endif
-
-int __bound_strlen(const char *s)
-{
- const char *p = s;
-
- dprintf(stderr, "%s, %s(): %p\n",
- __FILE__, __FUNCTION__, s);
- INCR_COUNT(bound_strlen_count);
- while (*p++);
- __bound_check(s, p - s, "strlen");
- return (p - s) - 1;
-}
-
-char *__bound_strcpy(char *dest, const char *src)
-{
- size_t len;
- const char *p = src;
-
- dprintf(stderr, "%s, %s(): %p, %p\n",
- __FILE__, __FUNCTION__, dest, src);
- INCR_COUNT(bound_strcpy_count);
- while (*p++);
- len = p - src;
- __bound_check(dest, len, "strcpy dest");
- __bound_check(src, len, "strcpy src");
- if (check_overlap(dest, len, src, len, "strcpy"))
- return dest;
- return strcpy (dest, src);
-}
-
-char *__bound_strncpy(char *dest, const char *src, size_t n)
-{
- size_t len = n;
- const char *p = src;
-
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_strncpy_count);
- while (len-- && *p++);
- len = p - src;
- __bound_check(dest, len, "strncpy dest");
- __bound_check(src, len, "strncpy src");
- if (check_overlap(dest, len, src, len, "strncpy"))
- return dest;
- return strncpy(dest, src, n);
-}
-
-int __bound_strcmp(const char *s1, const char *s2)
-{
- const unsigned char *u1 = (const unsigned char *) s1;
- const unsigned char *u2 = (const unsigned char *) s2;
-
- dprintf(stderr, "%s, %s(): %p, %p\n",
- __FILE__, __FUNCTION__, s1, s2);
- INCR_COUNT(bound_strcmp_count);
- while (*u1 && *u1 == *u2) {
- ++u1;
- ++u2;
- }
- __bound_check(s1, ((const char *)u1 - s1) + 1, "strcmp s1");
- __bound_check(s2, ((const char *)u2 - s2) + 1, "strcmp s2");
- return *u1 - *u2;
-}
-
-int __bound_strncmp(const char *s1, const char *s2, size_t n)
-{
- const unsigned char *u1 = (const unsigned char *) s1;
- const unsigned char *u2 = (const unsigned char *) s2;
- int retval = 0;
-
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, s1, s2, (unsigned long)n);
- INCR_COUNT(bound_strncmp_count);
- do {
- if ((ssize_t) --n == -1)
- break;
- else if (*u1 != *u2) {
- retval = *u1++ - *u2++;
- break;
- }
- ++u2;
- } while (*u1++);
- __bound_check(s1, (const char *)u1 - s1, "strncmp s1");
- __bound_check(s2, (const char *)u2 - s2, "strncmp s2");
- return retval;
-}
-
-char *__bound_strcat(char *dest, const char *src)
-{
- char *r = dest;
- const char *s = src;
-
- dprintf(stderr, "%s, %s(): %p, %p\n",
- __FILE__, __FUNCTION__, dest, src);
- INCR_COUNT(bound_strcat_count);
- while (*dest++);
- while (*src++);
- __bound_check(r, (dest - r) + (src - s) - 1, "strcat dest");
- __bound_check(s, src - s, "strcat src");
- if (check_overlap(r, (dest - r) + (src - s) - 1, s, src - s, "strcat"))
- return dest;
- return strcat(r, s);
-}
-
-char *__bound_strncat(char *dest, const char *src, size_t n)
-{
- char *r = dest;
- const char *s = src;
- size_t len = n;
-
- dprintf(stderr, "%s, %s(): %p, %p, 0x%lx\n",
- __FILE__, __FUNCTION__, dest, src, (unsigned long)n);
- INCR_COUNT(bound_strncat_count);
- while (*dest++);
- while (len-- && *src++);
- __bound_check(r, (dest - r) + (src - s) - 1, "strncat dest");
- __bound_check(s, src - s, "strncat src");
- if (check_overlap(r, (dest - r) + (src - s) - 1, s, src - s, "strncat"))
- return dest;
- return strncat(r, s, n);
-}
-
-char *__bound_strchr(const char *s, int c)
-{
- const unsigned char *str = (const unsigned char *) s;
- unsigned char ch = c;
-
- dprintf(stderr, "%s, %s(): %p, %d\n",
- __FILE__, __FUNCTION__, s, ch);
- INCR_COUNT(bound_strchr_count);
- while (*str) {
- if (*str == ch)
- break;
- ++str;
- }
- __bound_check(s, ((const char *)str - s) + 1, "strchr");
- return *str == ch ? (char *) str : NULL;
-}
-
-char *__bound_strrchr(const char *s, int c)
-{
- const unsigned char *str = (const unsigned char *) s;
- unsigned char ch = c;
-
- dprintf(stderr, "%s, %s(): %p, %d\n",
- __FILE__, __FUNCTION__, s, ch);
- INCR_COUNT(bound_strrchr_count);
- while (*str++);
- __bound_check(s, (const char *)str - s, "strrchr");
- while (str != (const unsigned char *)s) {
- if (*--str == ch)
- break;
- }
- __bound_check(s, (const char *)str - s, "strrchr");
- return *str == ch ? (char *) str : NULL;
-}
-
-char *__bound_strdup(const char *s)
-{
- const char *p = s;
- char *new;
-
- INCR_COUNT(bound_strdup_count);
- while (*p++);
- __bound_check(s, p - s, "strdup");
- new = BOUND_MALLOC ((p - s) + 1);
- dprintf(stderr, "%s, %s(): %p, 0x%lx\n",
- __FILE__, __FUNCTION__, new, (unsigned long)(p -s));
- if (new) {
- if (NO_CHECKING_GET() == 0 && no_strdup == 0) {
- WAIT_SEM ();
- tree = splay_insert((size_t)new, p - s, tree);
- if (tree && tree->start == (size_t) new)
- tree->type = TCC_TYPE_STRDUP;
- POST_SEM ();
- }
- memcpy (new, s, p - s);
- }
- return new;
-}
-
-/*
- An implementation of top-down splaying with sizes
- D. Sleator <sleator@cs.cmu.edu>, January 1994.
-
- This extends top-down-splay.c to maintain a size field in each node.
- This is the number of nodes in the subtree rooted there. This makes
- it possible to efficiently compute the rank of a key. (The rank is
- the number of nodes to the left of the given key.) It it also
- possible to quickly find the node of a given rank. Both of these
- operations are illustrated in the code below. The remainder of this
- introduction is taken from top-down-splay.c.
-
- "Splay trees", or "self-adjusting search trees" are a simple and
- efficient data structure for storing an ordered set. The data
- structure consists of a binary tree, with no additional fields. It
- allows searching, insertion, deletion, deletemin, deletemax,
- splitting, joining, and many other operations, all with amortized
- logarithmic performance. Since the trees adapt to the sequence of
- requests, their performance on real access patterns is typically even
- better. Splay trees are described in a number of texts and papers
- [1,2,3,4].
-
- The code here is adapted from simple top-down splay, at the bottom of
- page 669 of [2]. It can be obtained via anonymous ftp from
- spade.pc.cs.cmu.edu in directory /usr/sleator/public.
-
- The chief modification here is that the splay operation works even if the
- item being splayed is not in the tree, and even if the tree root of the
- tree is NULL. So the line:
-
- t = splay(i, t);
-
- causes it to search for item with key i in the tree rooted at t. If it's
- there, it is splayed to the root. If it isn't there, then the node put
- at the root is the last one before NULL that would have been reached in a
- normal binary search for i. (It's a neighbor of i in the tree.) This
- allows many other operations to be easily implemented, as shown below.
-
- [1] "Data Structures and Their Algorithms", Lewis and Denenberg,
- Harper Collins, 1991, pp 243-251.
- [2] "Self-adjusting Binary Search Trees" Sleator and Tarjan,
- JACM Volume 32, No 3, July 1985, pp 652-686.
- [3] "Data Structure and Algorithm Analysis", Mark Weiss,
- Benjamin Cummins, 1992, pp 119-130.
- [4] "Data Structures, Algorithms, and Performance", Derick Wood,
- Addison-Wesley, 1993, pp 367-375
-*/
-
-/* Code adapted for tcc */
-
-#define compare(start,tstart,tsize) (start < tstart ? -1 : \
- start >= tstart+tsize ? 1 : 0)
-
-static Tree * splay (size_t addr, Tree *t)
-/* Splay using the key start (which may or may not be in the tree.) */
-/* The starting root is t, and the tree used is defined by rat */
-{
- Tree N, *l, *r, *y;
- int comp;
-
- INCR_COUNT_SPLAY(bound_splay);
- if (t == NULL) return t;
- N.left = N.right = NULL;
- l = r = &N;
-
- for (;;) {
- comp = compare(addr, t->start, t->size);
- if (comp < 0) {
- y = t->left;
- if (y == NULL) break;
- if (compare(addr, y->start, y->size) < 0) {
- t->left = y->right; /* rotate right */
- y->right = t;
- t = y;
- if (t->left == NULL) break;
- }
- r->left = t; /* link right */
- r = t;
- t = t->left;
- } else if (comp > 0) {
- y = t->right;
- if (y == NULL) break;
- if (compare(addr, y->start, y->size) > 0) {
- t->right = y->left; /* rotate left */
- y->left = t;
- t = y;
- if (t->right == NULL) break;
- }
- l->right = t; /* link left */
- l = t;
- t = t->right;
- } else {
- break;
- }
- }
- l->right = t->left; /* assemble */
- r->left = t->right;
- t->left = N.right;
- t->right = N.left;
-
- return t;
-}
-
-#define compare_end(start,tend) (start < tend ? -1 : \
- start > tend ? 1 : 0)
-
-static Tree * splay_end (size_t addr, Tree *t)
-/* Splay using the key start (which may or may not be in the tree.) */
-/* The starting root is t, and the tree used is defined by rat */
-{
- Tree N, *l, *r, *y;
- int comp;
-
- INCR_COUNT_SPLAY(bound_splay_end);
- if (t == NULL) return t;
- N.left = N.right = NULL;
- l = r = &N;
-
- for (;;) {
- comp = compare_end(addr, t->start + t->size);
- if (comp < 0) {
- y = t->left;
- if (y == NULL) break;
- if (compare_end(addr, y->start + y->size) < 0) {
- t->left = y->right; /* rotate right */
- y->right = t;
- t = y;
- if (t->left == NULL) break;
- }
- r->left = t; /* link right */
- r = t;
- t = t->left;
- } else if (comp > 0) {
- y = t->right;
- if (y == NULL) break;
- if (compare_end(addr, y->start + y->size) > 0) {
- t->right = y->left; /* rotate left */
- y->left = t;
- t = y;
- if (t->right == NULL) break;
- }
- l->right = t; /* link left */
- l = t;
- t = t->right;
- } else {
- break;
- }
- }
- l->right = t->left; /* assemble */
- r->left = t->right;
- t->left = N.right;
- t->right = N.left;
-
- return t;
-}
-
-static Tree * splay_insert(size_t addr, size_t size, Tree * t)
-/* Insert key start into the tree t, if it is not already there. */
-/* Return a pointer to the resulting tree. */
-{
- Tree * new;
-
- INCR_COUNT_SPLAY(bound_splay_insert);
- if (t != NULL) {
- t = splay(addr,t);
- if (compare(addr, t->start, t->size)==0) {
- return t; /* it's already there */
- }
- }
-#if TREE_REUSE
- if (tree_free_list) {
- new = tree_free_list;
- tree_free_list = new->left;
- }
- else
-#endif
- {
- new = (Tree *) BOUND_MALLOC (sizeof (Tree));
- }
- if (new == NULL) {
- bound_alloc_error("not enough memory for bound checking code");
- }
- else {
- if (t == NULL) {
- new->left = new->right = NULL;
- } else if (compare(addr, t->start, t->size) < 0) {
- new->left = t->left;
- new->right = t;
- t->left = NULL;
- } else {
- new->right = t->right;
- new->left = t;
- t->right = NULL;
- }
- new->start = addr;
- new->size = size;
- new->type = TCC_TYPE_NONE;
- new->is_invalid = 0;
- }
- return new;
-}
-
-#define compare_destroy(start,tstart) (start < tstart ? -1 : \
- start > tstart ? 1 : 0)
-
-static Tree * splay_delete(size_t addr, Tree *t)
-/* Deletes addr from the tree if it's there. */
-/* Return a pointer to the resulting tree. */
-{
- Tree * x;
-
- INCR_COUNT_SPLAY(bound_splay_delete);
- if (t==NULL) return NULL;
- t = splay(addr,t);
- if (compare_destroy(addr, t->start) == 0) { /* found it */
- if (t->left == NULL) {
- x = t->right;
- } else {
- x = splay(addr, t->left);
- x->right = t->right;
- }
-#if TREE_REUSE
- t->left = tree_free_list;
- tree_free_list = t;
-#else
- BOUND_FREE(t);
-#endif
- return x;
- } else {
- return t; /* It wasn't there */
- }
-}
-
-void splay_printtree(Tree * t, int d)
-{
- int i;
- if (t == NULL) return;
- splay_printtree(t->right, d+1);
- for (i=0; i<d; i++) fprintf(stderr," ");
- fprintf(stderr,"%p(0x%lx:%u:%u)\n",
- (void *) t->start, (unsigned long) t->size,
- (unsigned)t->type, (unsigned)t->is_invalid);
- splay_printtree(t->left, d+1);
-}
diff --git a/tinycc/lib/bt-dll.c b/tinycc/lib/bt-dll.c
deleted file mode 100644
index 7c62cef..0000000
--- a/tinycc/lib/bt-dll.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* ------------------------------------------------------------- */
-/* stubs for calling bcheck functions from a dll. */
-
-#include <windows.h>
-#include <stdio.h>
-
-#define REDIR_ALL \
- REDIR(__bt_init) \
- REDIR(__bt_exit) \
- REDIR(tcc_backtrace) \
- \
- REDIR(__bound_ptr_add) \
- REDIR(__bound_ptr_indir1) \
- REDIR(__bound_ptr_indir2) \
- REDIR(__bound_ptr_indir4) \
- REDIR(__bound_ptr_indir8) \
- REDIR(__bound_ptr_indir12) \
- REDIR(__bound_ptr_indir16) \
- REDIR(__bound_local_new) \
- REDIR(__bound_local_delete) \
- REDIR(__bound_new_region) \
- \
- REDIR(__bound_free) \
- REDIR(__bound_malloc) \
- REDIR(__bound_realloc) \
- REDIR(__bound_memcpy) \
- REDIR(__bound_memcmp) \
- REDIR(__bound_memmove) \
- REDIR(__bound_memset) \
- REDIR(__bound_strlen) \
- REDIR(__bound_strcpy) \
- REDIR(__bound_strncpy) \
- REDIR(__bound_strcmp) \
- REDIR(__bound_strncmp) \
- REDIR(__bound_strcat) \
- REDIR(__bound_strchr) \
- REDIR(__bound_strdup)
-
-#ifdef __leading_underscore
-#define _(s) "_"#s
-#else
-#define _(s) #s
-#endif
-
-#define REDIR(s) void *s;
-static struct { REDIR_ALL } all_ptrs;
-#undef REDIR
-#define REDIR(s) #s"\0"
-static const char all_names[] = REDIR_ALL;
-#undef REDIR
-#define REDIR(s) __asm__(".global " _(s) ";" _(s) ": jmp *%0" : : "m" (all_ptrs.s) );
-static void all_jmps() { REDIR_ALL }
-#undef REDIR
-
-void __bt_init_dll(int bcheck)
-{
- const char *s = all_names;
- void **p = (void**)&all_ptrs;
- do {
- *p = (void*)GetProcAddress(GetModuleHandle(NULL), (char*)s);
- if (NULL == *p) {
- char buf[100];
- sprintf(buf,
- "Error: function '%s()' not found in executable. "
- "(Need -bt or -b for linking the exe.)", s);
- if (GetStdHandle(STD_ERROR_HANDLE))
- fprintf(stderr, "TCC/BCHECK: %s\n", buf), fflush(stderr);
- else
- MessageBox(NULL, buf, "TCC/BCHECK", MB_ICONERROR);
- ExitProcess(1);
- }
- s = strchr(s,'\0') + 1, ++p;
- } while (*s && (bcheck || p < &all_ptrs.__bound_ptr_add));
-}
diff --git a/tinycc/lib/bt-exe.c b/tinycc/lib/bt-exe.c
deleted file mode 100644
index 3a2d02e..0000000
--- a/tinycc/lib/bt-exe.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* ------------------------------------------------------------- */
-/* for linking rt_printline and the signal/exception handler
- from tccrun.c into executables. */
-
-#define CONFIG_TCC_BACKTRACE_ONLY
-#define ONE_SOURCE 1
-#define pstrcpy tcc_pstrcpy
-#include "../tccrun.c"
-
-int (*__rt_error)(void*, void*, const char *, va_list);
-__attribute__((weak)) void __bound_checking_lock(void);
-__attribute__((weak)) void __bound_checking_unlock(void);
-
-#ifndef _WIN32
-# define __declspec(n)
-#endif
-
-__declspec(dllexport)
-void __bt_init(rt_context *p, int num_callers)
-{
- __attribute__((weak)) int main();
- __attribute__((weak)) void __bound_init(void*, int);
- struct rt_context *rc = &g_rtctxt;
- //fprintf(stderr, "__bt_init %d %p %p\n", num_callers, p->stab_sym, p->bounds_start), fflush(stderr);
- /* call __bound_init here due to redirection of sigaction */
- /* needed to add global symbols */
- if (p->bounds_start) {
- __bound_init(p->bounds_start, -1);
- __bound_checking_lock();
- }
- if (num_callers) {
- memcpy(rc, p, offsetof(rt_context, next));
- rc->num_callers = num_callers - 1;
- rc->top_func = main;
- __rt_error = _rt_error;
- set_exception_handler();
- } else {
- p->next = rc->next, rc->next = p;
- }
- if (p->bounds_start)
- __bound_checking_unlock();
-}
-
-__declspec(dllexport)
-void __bt_exit(rt_context *p)
-{
- __attribute__((weak)) void __bound_exit_dll(void*);
- struct rt_context *rc = &g_rtctxt;
-
- if (p->bounds_start) {
- __bound_exit_dll(p->bounds_start);
- __bound_checking_lock();
- }
- while (rc) {
- if (rc->next == p) {
- rc->next = rc->next->next;
- break;
- }
- rc = rc->next;
- }
- if (p->bounds_start)
- __bound_checking_unlock();
-}
-
-/* copy a string and truncate it. */
-ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s)
-{
- int l = strlen(s);
- if (l >= buf_size)
- l = buf_size - 1;
- memcpy(buf, s, l);
- buf[l] = 0;
- return buf;
-}
diff --git a/tinycc/lib/bt-log.c b/tinycc/lib/bt-log.c
deleted file mode 100644
index 8f7a4db..0000000
--- a/tinycc/lib/bt-log.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ------------------------------------------------------------- */
-/* function to get a stack backtrace on demand with a message */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-int (*__rt_error)(void*, void*, const char *, va_list);
-
-#ifdef _WIN32
-# define DLL_EXPORT __declspec(dllexport)
-#else
-# define DLL_EXPORT
-#endif
-
-/* Needed when using ...libtcc1-usegcc=yes in lib/Makefile */
-#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-address"
-#endif
-
-DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- if (__rt_error) {
- void *fp = __builtin_frame_address(1);
- void *ip = __builtin_return_address(0);
- va_start(ap, fmt);
- ret = __rt_error(fp, ip, fmt, ap);
- va_end(ap);
- } else {
- const char *p;
- if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
- fmt = p + 1;
- va_start(ap, fmt);
- ret = vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n"), fflush(stderr);
- }
- return ret;
-}
-
-#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
diff --git a/tinycc/lib/builtin.c b/tinycc/lib/builtin.c
deleted file mode 100644
index e40a003..0000000
--- a/tinycc/lib/builtin.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/* uses alias to allow building with gcc/clang */
-#ifdef __TINYC__
-#define BUILTIN(x) __builtin_##x
-#define BUILTINN(x) "__builtin_" # x
-#else
-#define BUILTIN(x) __tcc_builtin_##x
-#define BUILTINN(x) "__tcc_builtin_" # x
-#endif
-
-/* ---------------------------------------------- */
-/* This file implements:
- * __builtin_ffs
- * __builtin_clz
- * __builtin_ctz
- * __builtin_clrsb
- * __builtin_popcount
- * __builtin_parity
- * for int, long and long long
- */
-
-static const unsigned char table_1_32[] = {
- 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
-};
-static const unsigned char table_2_32[32] = {
- 31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
- 23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0
-};
-static const unsigned char table_1_64[] = {
- 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
- 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
- 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
- 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
-};
-static const unsigned char table_2_64[] = {
- 63, 16, 62, 7, 15, 36, 61, 3, 6, 14, 22, 26, 35, 47, 60, 2,
- 9, 5, 28, 11, 13, 21, 42, 19, 25, 31, 34, 40, 46, 52, 59, 1,
- 17, 8, 37, 4, 23, 27, 48, 10, 29, 12, 43, 20, 32, 41, 53, 18,
- 38, 24, 49, 30, 44, 33, 54, 39, 50, 45, 55, 51, 56, 57, 58, 0
-};
-
-#define FFSI(x) \
- return table_1_32[((x & -x) * 0x077cb531u) >> 27] + (x != 0);
-#define FFSL(x) \
- return table_1_64[((x & -x) * 0x022fdd63cc95386dull) >> 58] + (x != 0);
-#define CTZI(x) \
- return table_1_32[((x & -x) * 0x077cb531u) >> 27];
-#define CTZL(x) \
- return table_1_64[((x & -x) * 0x022fdd63cc95386dull) >> 58];
-#define CLZI(x) \
- x |= x >> 1; \
- x |= x >> 2; \
- x |= x >> 4; \
- x |= x >> 8; \
- x |= x >> 16; \
- return table_2_32[(x * 0x07c4acddu) >> 27];
-#define CLZL(x) \
- x |= x >> 1; \
- x |= x >> 2; \
- x |= x >> 4; \
- x |= x >> 8; \
- x |= x >> 16; \
- x |= x >> 32; \
- return table_2_64[x * 0x03f79d71b4cb0a89ull >> 58];
-#define POPCOUNTI(x, m) \
- x = x - ((x >> 1) & 0x55555555); \
- x = (x & 0x33333333) + ((x >> 2) & 0x33333333); \
- x = (x + (x >> 4)) & 0xf0f0f0f; \
- return ((x * 0x01010101) >> 24) & m;
-#define POPCOUNTL(x, m) \
- x = x - ((x >> 1) & 0x5555555555555555ull); \
- x = (x & 0x3333333333333333ull) + ((x >> 2) & 0x3333333333333333ull); \
- x = (x + (x >> 4)) & 0xf0f0f0f0f0f0f0full; \
- return ((x * 0x0101010101010101ull) >> 56) & m;
-
-/* Returns one plus the index of the least significant 1-bit of x,
- or if x is zero, returns zero. */
-int BUILTIN(ffs) (int x) { FFSI(x) }
-int BUILTIN(ffsll) (long long x) { FFSL(x) }
-#if __SIZEOF_LONG__ == 4
-int BUILTIN(ffsl) (long x) __attribute__((alias(BUILTINN(ffs))));
-#else
-int BUILTIN(ffsl) (long x) __attribute__((alias(BUILTINN(ffsll))));
-#endif
-
-/* Returns the number of leading 0-bits in x, starting at the most significant
- bit position. If x is 0, the result is undefined. */
-int BUILTIN(clz) (unsigned int x) { CLZI(x) }
-int BUILTIN(clzll) (unsigned long long x) { CLZL(x) }
-#if __SIZEOF_LONG__ == 4
-int BUILTIN(clzl) (unsigned long x) __attribute__((alias(BUILTINN(clz))));
-#else
-int BUILTIN(clzl) (unsigned long x) __attribute__((alias(BUILTINN(clzll))));
-#endif
-
-/* Returns the number of trailing 0-bits in x, starting at the least
- significant bit position. If x is 0, the result is undefined. */
-int BUILTIN(ctz) (unsigned int x) { CTZI(x) }
-int BUILTIN(ctzll) (unsigned long long x) { CTZL(x) }
-#if __SIZEOF_LONG__ == 4
-int BUILTIN(ctzl) (unsigned long x) __attribute__((alias(BUILTINN(ctz))));
-#else
-int BUILTIN(ctzl) (unsigned long x) __attribute__((alias(BUILTINN(ctzll))));
-#endif
-
-/* Returns the number of leading redundant sign bits in x, i.e. the number
- of bits following the most significant bit that are identical to it.
- There are no special cases for 0 or other values. */
-int BUILTIN(clrsb) (int x) { if (x < 0) x = ~x; x <<= 1; CLZI(x) }
-int BUILTIN(clrsbll) (long long x) { if (x < 0) x = ~x; x <<= 1; CLZL(x) }
-#if __SIZEOF_LONG__ == 4
-int BUILTIN(clrsbl) (long x) __attribute__((alias(BUILTINN(clrsb))));
-#else
-int BUILTIN(clrsbl) (long x) __attribute__((alias(BUILTINN(clrsbll))));
-#endif
-
-/* Returns the number of 1-bits in x.*/
-int BUILTIN(popcount) (unsigned int x) { POPCOUNTI(x, 0x3f) }
-int BUILTIN(popcountll) (unsigned long long x) { POPCOUNTL(x, 0x7f) }
-#if __SIZEOF_LONG__ == 4
-int BUILTIN(popcountl) (unsigned long x) __attribute__((alias(BUILTINN(popcount))));
-#else
-int BUILTIN(popcountl ) (unsigned long x) __attribute__((alias(BUILTINN(popcountll))));
-#endif
-
-/* Returns the parity of x, i.e. the number of 1-bits in x modulo 2. */
-int BUILTIN(parity) (unsigned int x) { POPCOUNTI(x, 0x01) }
-int BUILTIN(parityll) (unsigned long long x) { POPCOUNTL(x, 0x01) }
-#if __SIZEOF_LONG__ == 4
-int BUILTIN(parityl) (unsigned long x) __attribute__((alias(BUILTINN(parity))));
-#else
-int BUILTIN(parityl) (unsigned long x) __attribute__((alias(BUILTINN(parityll))));
-#endif
-
-#ifndef __TINYC__
-#if defined(__GNUC__) && (__GNUC__ >= 6)
-/* gcc overrides alias from __builtin_ffs... to ffs.. so use assembly code */
-__asm__(".globl __builtin_ffs");
-__asm__(".set __builtin_ffs,__tcc_builtin_ffs");
-__asm__(".globl __builtin_ffsl");
-__asm__(".set __builtin_ffsl,__tcc_builtin_ffsl");
-__asm__(".globl __builtin_ffsll");
-__asm__(".set __builtin_ffsll,__tcc_builtin_ffsll");
-#else
-int __builtin_ffs(int x) __attribute__((alias("__tcc_builtin_ffs")));
-int __builtin_ffsl(long x) __attribute__((alias("__tcc_builtin_ffsl")));
-int __builtin_ffsll(long long x) __attribute__((alias("__tcc_builtin_ffsll")));
-#endif
-int __builtin_clz(unsigned int x) __attribute__((alias("__tcc_builtin_clz")));
-int __builtin_clzl(unsigned long x) __attribute__((alias("__tcc_builtin_clzl")));
-int __builtin_clzll(unsigned long long x) __attribute__((alias("__tcc_builtin_clzll")));
-int __builtin_ctz(unsigned int x) __attribute__((alias("__tcc_builtin_ctz")));
-int __builtin_ctzl(unsigned long x) __attribute__((alias("__tcc_builtin_ctzl")));
-int __builtin_ctzll(unsigned long long x) __attribute__((alias("__tcc_builtin_ctzll")));
-int __builtin_clrsb(int x) __attribute__((alias("__tcc_builtin_clrsb")));
-int __builtin_clrsbl(long x) __attribute__((alias("__tcc_builtin_clrsbl")));
-int __builtin_clrsbll(long long x) __attribute__((alias("__tcc_builtin_clrsbll")));
-int __builtin_popcount(unsigned int x) __attribute__((alias("__tcc_builtin_popcount")));
-int __builtin_popcountl(unsigned long x) __attribute__((alias("__tcc_builtin_popcountl")));
-int __builtin_popcountll(unsigned long long x) __attribute__((alias("__tcc_builtin_popcountll")));
-int __builtin_parity(unsigned int x) __attribute__((alias("__tcc_builtin_parity")));
-int __builtin_parityl(unsigned long x) __attribute__((alias("__tcc_builtin_parityl")));
-int __builtin_parityll(unsigned long long x) __attribute__((alias("__tcc_builtin_parityll")));
-#endif
diff --git a/tinycc/lib/dsohandle.c b/tinycc/lib/dsohandle.c
deleted file mode 100644
index 0993dbc..0000000
--- a/tinycc/lib/dsohandle.c
+++ /dev/null
@@ -1 +0,0 @@
-void * __dso_handle __attribute((visibility("hidden"))) = &__dso_handle;
diff --git a/tinycc/lib/lib-arm64.c b/tinycc/lib/lib-arm64.c
deleted file mode 100644
index 226827e..0000000
--- a/tinycc/lib/lib-arm64.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * TCC runtime library for arm64.
- *
- * Copyright (c) 2015 Edmund Grimley Evans
- *
- * Copying and distribution of this file, with or without modification,
- * are permitted in any medium without royalty provided the copyright
- * notice and this notice are preserved. This file is offered as-is,
- * without any warranty.
- */
-
-#ifdef __TINYC__
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef int int32_t;
-typedef unsigned uint32_t;
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
-void *memcpy(void*,void*,__SIZE_TYPE__);
-#else
-#include <stdint.h>
-#include <string.h>
-#endif
-
-#if !defined __riscv && !defined __APPLE__
-void __clear_cache(void *beg, void *end)
-{
- __arm64_clear_cache(beg, end);
-}
-#endif
-
-typedef struct {
- uint64_t x0, x1;
-} u128_t;
-
-static long double f3_zero(int sgn)
-{
- long double f;
- u128_t x = { 0, (uint64_t)sgn << 63 };
- memcpy(&f, &x, 16);
- return f;
-}
-
-static long double f3_infinity(int sgn)
-{
- long double f;
- u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 };
- memcpy(&f, &x, 16);
- return f;
-}
-
-static long double f3_NaN(void)
-{
- long double f;
-#if 0
- // ARM's default NaN usually has just the top fraction bit set:
- u128_t x = { 0, 0x7fff800000000000 };
-#else
- // GCC's library sets all fraction bits:
- u128_t x = { -1, 0x7fffffffffffffff };
-#endif
- memcpy(&f, &x, 16);
- return f;
-}
-
-static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt)
-{
- u128_t x = { mnt.x0,
- mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 };
- memcpy(f, &x, 16);
- return 1;
-}
-
-static int fp3_detect_NaNs(long double *f,
- int a_sgn, int a_exp, u128_t a,
- int b_sgn, int b_exp, u128_t b)
-{
- // Detect signalling NaNs:
- if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1))
- return fp3_convert_NaN(f, a_sgn, a);
- if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1))
- return fp3_convert_NaN(f, b_sgn, b);
-
- // Detect quiet NaNs:
- if (a_exp == 32767 && (a.x0 | a.x1 << 16))
- return fp3_convert_NaN(f, a_sgn, a);
- if (b_exp == 32767 && (b.x0 | b.x1 << 16))
- return fp3_convert_NaN(f, b_sgn, b);
-
- return 0;
-}
-
-static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f)
-{
- u128_t x;
- memcpy(&x, &f, 16);
- *sgn = x.x1 >> 63;
- *exp = x.x1 >> 48 & 32767;
- x.x1 = x.x1 << 16 >> 16;
- if (*exp)
- x.x1 |= (uint64_t)1 << 48;
- else
- *exp = 1;
- *mnt = x;
-}
-
-static u128_t f3_normalise(int32_t *exp, u128_t mnt)
-{
- int sh;
- if (!(mnt.x0 | mnt.x1))
- return mnt;
- if (!mnt.x1) {
- mnt.x1 = mnt.x0;
- mnt.x0 = 0;
- *exp -= 64;
- }
- for (sh = 32; sh; sh >>= 1) {
- if (!(mnt.x1 >> (64 - sh))) {
- mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh);
- mnt.x0 = mnt.x0 << sh;
- *exp -= sh;
- }
- }
- return mnt;
-}
-
-static u128_t f3_sticky_shift(int32_t sh, u128_t x)
-{
- if (sh >= 128) {
- x.x0 = !!(x.x0 | x.x1);
- x.x1 = 0;
- return x;
- }
- if (sh >= 64) {
- x.x0 = x.x1 | !!x.x0;
- x.x1 = 0;
- sh -= 64;
- }
- if (sh > 0) {
- x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh));
- x.x1 = x.x1 >> sh;
- }
- return x;
-}
-
-static long double f3_round(int sgn, int32_t exp, u128_t x)
-{
- long double f;
- int error;
-
- if (exp > 0) {
- x = f3_sticky_shift(13, x);
- }
- else {
- x = f3_sticky_shift(14 - exp, x);
- exp = 0;
- }
-
- error = x.x0 & 3;
- x.x0 = x.x0 >> 2 | x.x1 << 62;
- x.x1 = x.x1 >> 2;
-
- if (error == 3 || ((error == 2) & (x.x0 & 1))) {
- if (!++x.x0) {
- ++x.x1;
- if (x.x1 == (uint64_t)1 << 48)
- exp = 1;
- else if (x.x1 == (uint64_t)1 << 49) {
- ++exp;
- x.x0 = x.x0 >> 1 | x.x1 << 63;
- x.x1 = x.x1 >> 1;
- }
- }
- }
-
- if (exp >= 32767)
- return f3_infinity(sgn);
-
- x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63;
- memcpy(&f, &x, 16);
- return f;
-}
-
-static long double f3_add(long double fa, long double fb, int neg)
-{
- u128_t a, b, x;
- int32_t a_exp, b_exp, x_exp;
- int a_sgn, b_sgn, x_sgn;
- long double fx;
-
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- f3_unpack(&b_sgn, &b_exp, &b, fb);
-
- if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
- return fx;
-
- b_sgn ^= neg;
-
- // Handle infinities and zeroes:
- if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn)
- return f3_NaN();
- if (a_exp == 32767)
- return f3_infinity(a_sgn);
- if (b_exp == 32767)
- return f3_infinity(b_sgn);
- if (!(a.x0 | a.x1 | b.x0 | b.x1))
- return f3_zero(a_sgn & b_sgn);
-
- a.x1 = a.x1 << 3 | a.x0 >> 61;
- a.x0 = a.x0 << 3;
- b.x1 = b.x1 << 3 | b.x0 >> 61;
- b.x0 = b.x0 << 3;
-
- if (a_exp <= b_exp) {
- a = f3_sticky_shift(b_exp - a_exp, a);
- a_exp = b_exp;
- }
- else {
- b = f3_sticky_shift(a_exp - b_exp, b);
- b_exp = a_exp;
- }
-
- x_sgn = a_sgn;
- x_exp = a_exp;
- if (a_sgn == b_sgn) {
- x.x0 = a.x0 + b.x0;
- x.x1 = a.x1 + b.x1 + (x.x0 < a.x0);
- }
- else {
- x.x0 = a.x0 - b.x0;
- x.x1 = a.x1 - b.x1 - (x.x0 > a.x0);
- if (x.x1 >> 63) {
- x_sgn ^= 1;
- x.x0 = -x.x0;
- x.x1 = -x.x1 - !!x.x0;
- }
- }
-
- if (!(x.x0 | x.x1))
- return f3_zero(0);
-
- x = f3_normalise(&x_exp, x);
-
- return f3_round(x_sgn, x_exp + 12, x);
-}
-
-long double __addtf3(long double a, long double b)
-{
- return f3_add(a, b, 0);
-}
-
-long double __subtf3(long double a, long double b)
-{
- return f3_add(a, b, 1);
-}
-
-long double __multf3(long double fa, long double fb)
-{
- u128_t a, b, x;
- int32_t a_exp, b_exp, x_exp;
- int a_sgn, b_sgn, x_sgn;
- long double fx;
-
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- f3_unpack(&b_sgn, &b_exp, &b, fb);
-
- if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
- return fx;
-
- // Handle infinities and zeroes:
- if ((a_exp == 32767 && !(b.x0 | b.x1)) ||
- (b_exp == 32767 && !(a.x0 | a.x1)))
- return f3_NaN();
- if (a_exp == 32767 || b_exp == 32767)
- return f3_infinity(a_sgn ^ b_sgn);
- if (!(a.x0 | a.x1) || !(b.x0 | b.x1))
- return f3_zero(a_sgn ^ b_sgn);
-
- a = f3_normalise(&a_exp, a);
- b = f3_normalise(&b_exp, b);
-
- x_sgn = a_sgn ^ b_sgn;
- x_exp = a_exp + b_exp - 16352;
-
- {
- // Convert to base (1 << 30), discarding bottom 6 bits, which are zero,
- // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0):
- uint64_t a0 = a.x0 << 28 >> 34;
- uint64_t b0 = b.x0 << 28 >> 34;
- uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34;
- uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34;
- uint64_t a2 = a.x1 << 32 >> 34;
- uint64_t b2 = b.x1 << 32 >> 34;
- uint64_t a3 = a.x1 >> 32;
- uint64_t b3 = b.x1 >> 32;
- // Use 16 small multiplications and additions that do not overflow:
- uint64_t x0 = a0 * b0;
- uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0;
- uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0;
- uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
- uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1;
- uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2;
- uint64_t x6 = (x5 >> 30) + a3 * b3;
- // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...).
- // Take the top 128 bits, setting bottom bit if any lower bits were set:
- uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 |
- !!(x3 << 38 | (x2 | x1 | x0) << 34));
- uint64_t y1 = x6;
- // Top bit may be zero. Renormalise:
- if (!(y1 >> 63)) {
- y1 = y1 << 1 | y0 >> 63;
- y0 = y0 << 1;
- --x_exp;
- }
- x.x0 = y0;
- x.x1 = y1;
- }
-
- return f3_round(x_sgn, x_exp, x);
-}
-
-long double __divtf3(long double fa, long double fb)
-{
- u128_t a, b, x;
- int32_t a_exp, b_exp, x_exp;
- int a_sgn, b_sgn, x_sgn, i;
- long double fx;
-
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- f3_unpack(&b_sgn, &b_exp, &b, fb);
-
- if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
- return fx;
-
- // Handle infinities and zeroes:
- if ((a_exp == 32767 && b_exp == 32767) ||
- (!(a.x0 | a.x1) && !(b.x0 | b.x1)))
- return f3_NaN();
- if (a_exp == 32767 || !(b.x0 | b.x1))
- return f3_infinity(a_sgn ^ b_sgn);
- if (!(a.x0 | a.x1) || b_exp == 32767)
- return f3_zero(a_sgn ^ b_sgn);
-
- a = f3_normalise(&a_exp, a);
- b = f3_normalise(&b_exp, b);
-
- x_sgn = a_sgn ^ b_sgn;
- x_exp = a_exp - b_exp + 16395;
-
- a.x0 = a.x0 >> 1 | a.x1 << 63;
- a.x1 = a.x1 >> 1;
- b.x0 = b.x0 >> 1 | b.x1 << 63;
- b.x1 = b.x1 >> 1;
- x.x0 = 0;
- x.x1 = 0;
- for (i = 0; i < 116; i++) {
- x.x1 = x.x1 << 1 | x.x0 >> 63;
- x.x0 = x.x0 << 1;
- if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) {
- a.x1 = a.x1 - b.x1 - (a.x0 < b.x0);
- a.x0 = a.x0 - b.x0;
- x.x0 |= 1;
- }
- a.x1 = a.x1 << 1 | a.x0 >> 63;
- a.x0 = a.x0 << 1;
- }
- x.x0 |= !!(a.x0 | a.x1);
-
- x = f3_normalise(&x_exp, x);
-
- return f3_round(x_sgn, x_exp, x);
-}
-
-long double __extendsftf2(float f)
-{
- long double fx;
- u128_t x;
- uint32_t a;
- uint64_t aa;
- memcpy(&a, &f, 4);
- aa = a;
- x.x0 = 0;
- if (!(a << 1))
- x.x1 = aa << 32;
- else if (a << 1 >> 24 == 255)
- x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 |
- (uint64_t)!!(a << 9) << 47);
- else if (a << 1 >> 24 == 0) {
- uint64_t adj = 0;
- while (!(a << 1 >> 1 >> (23 - adj)))
- adj++;
- x.x1 = aa >> 31 << 63 | (16256 - adj + 1) << 48 | aa << adj << 41 >> 16;
- } else
- x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 |
- aa << 41 >> 16);
- memcpy(&fx, &x, 16);
- return fx;
-}
-
-long double __extenddftf2(double f)
-{
- long double fx;
- u128_t x;
- uint64_t a;
- memcpy(&a, &f, 8);
- x.x0 = a << 60;
- if (!(a << 1))
- x.x1 = a;
- else if (a << 1 >> 53 == 2047)
- x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 |
- (uint64_t)!!(a << 12) << 47);
- else if (a << 1 >> 53 == 0) {
- uint64_t adj = 0;
- while (!(a << 1 >> 1 >> (52 - adj)))
- adj++;
- x.x0 <<= adj;
- x.x1 = a >> 63 << 63 | (15360 - adj + 1) << 48 | a << adj << 12 >> 16;
- } else
- x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16;
- memcpy(&fx, &x, 16);
- return fx;
-}
-
-float __trunctfsf2(long double f)
-{
- u128_t mnt;
- int32_t exp;
- int sgn;
- uint32_t x;
- float fx;
-
- f3_unpack(&sgn, &exp, &mnt, f);
-
- if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
- x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff);
- else if (exp > 16510)
- x = 0x7f800000 | (uint32_t)sgn << 31;
- else if (exp < 16233)
- x = (uint32_t)sgn << 31;
- else {
- exp -= 16257;
- x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41);
- if (exp < 0) {
- x = x >> -exp | !!(x << (32 + exp));
- exp = 0;
- }
- if ((x & 3) == 3 || (x & 7) == 6)
- x += 4;
- x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31;
- }
- memcpy(&fx, &x, 4);
- return fx;
-}
-
-double __trunctfdf2(long double f)
-{
- u128_t mnt;
- int32_t exp;
- int sgn;
- uint64_t x;
- double fx;
-
- f3_unpack(&sgn, &exp, &mnt, f);
-
- if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
- x = (0x7ff8000000000000 | (uint64_t)sgn << 63 |
- mnt.x1 << 16 >> 12 | mnt.x0 >> 60);
- else if (exp > 17406)
- x = 0x7ff0000000000000 | (uint64_t)sgn << 63;
- else if (exp < 15308)
- x = (uint64_t)sgn << 63;
- else {
- exp -= 15361;
- x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6);
- if (exp < 0) {
- x = x >> -exp | !!(x << (64 + exp));
- exp = 0;
- }
- if ((x & 3) == 3 || (x & 7) == 6)
- x += 4;
- x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63;
- }
- memcpy(&fx, &x, 8);
- return fx;
-}
-
-int32_t __fixtfsi(long double fa)
-{
- u128_t a;
- int32_t a_exp;
- int a_sgn;
- int32_t x;
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- if (a_exp < 16369)
- return 0;
- if (a_exp > 16413)
- return a_sgn ? -0x80000000 : 0x7fffffff;
- x = a.x1 >> (16431 - a_exp);
- return a_sgn ? -x : x;
-}
-
-int64_t __fixtfdi(long double fa)
-{
- u128_t a;
- int32_t a_exp;
- int a_sgn;
- int64_t x;
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- if (a_exp < 16383)
- return 0;
- if (a_exp > 16445)
- return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff;
- x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
- return a_sgn ? -x : x;
-}
-
-uint32_t __fixunstfsi(long double fa)
-{
- u128_t a;
- int32_t a_exp;
- int a_sgn;
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- if (a_sgn || a_exp < 16369)
- return 0;
- if (a_exp > 16414)
- return -1;
- return a.x1 >> (16431 - a_exp);
-}
-
-uint64_t __fixunstfdi(long double fa)
-{
- u128_t a;
- int32_t a_exp;
- int a_sgn;
- f3_unpack(&a_sgn, &a_exp, &a, fa);
- if (a_sgn || a_exp < 16383)
- return 0;
- if (a_exp > 16446)
- return -1;
- return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
-}
-
-long double __floatsitf(int32_t a)
-{
- int sgn = 0;
- int exp = 16414;
- uint32_t mnt = a;
- u128_t x = { 0, 0 };
- long double f;
- int i;
- if (a) {
- if (a < 0) {
- sgn = 1;
- mnt = -mnt;
- }
- for (i = 16; i; i >>= 1)
- if (!(mnt >> (32 - i))) {
- mnt <<= i;
- exp -= i;
- }
- x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 |
- (uint64_t)(mnt << 1) << 16);
- }
- memcpy(&f, &x, 16);
- return f;
-}
-
-long double __floatditf(int64_t a)
-{
- int sgn = 0;
- int exp = 16446;
- uint64_t mnt = a;
- u128_t x = { 0, 0 };
- long double f;
- int i;
- if (a) {
- if (a < 0) {
- sgn = 1;
- mnt = -mnt;
- }
- for (i = 32; i; i >>= 1)
- if (!(mnt >> (64 - i))) {
- mnt <<= i;
- exp -= i;
- }
- x.x0 = mnt << 49;
- x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16;
- }
- memcpy(&f, &x, 16);
- return f;
-}
-
-long double __floatunsitf(uint32_t a)
-{
- int exp = 16414;
- uint32_t mnt = a;
- u128_t x = { 0, 0 };
- long double f;
- int i;
- if (a) {
- for (i = 16; i; i >>= 1)
- if (!(mnt >> (32 - i))) {
- mnt <<= i;
- exp -= i;
- }
- x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16;
- }
- memcpy(&f, &x, 16);
- return f;
-}
-
-long double __floatunditf(uint64_t a)
-{
- int exp = 16446;
- uint64_t mnt = a;
- u128_t x = { 0, 0 };
- long double f;
- int i;
- if (a) {
- for (i = 32; i; i >>= 1)
- if (!(mnt >> (64 - i))) {
- mnt <<= i;
- exp -= i;
- }
- x.x0 = mnt << 49;
- x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16;
- }
- memcpy(&f, &x, 16);
- return f;
-}
-
-static int f3_cmp(long double fa, long double fb)
-{
- u128_t a, b;
- memcpy(&a, &fa, 16);
- memcpy(&b, &fb, 16);
- return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 :
- ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) ||
- (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 :
- a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) :
- a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 :
- a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) :
- a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 :
- b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0);
-}
-
-int __eqtf2(long double a, long double b)
-{
- return !!f3_cmp(a, b);
-}
-
-int __netf2(long double a, long double b)
-{
- return !!f3_cmp(a, b);
-}
-
-int __lttf2(long double a, long double b)
-{
- return f3_cmp(a, b);
-}
-
-int __letf2(long double a, long double b)
-{
- return f3_cmp(a, b);
-}
-
-int __gttf2(long double a, long double b)
-{
- return -f3_cmp(b, a);
-}
-
-int __getf2(long double a, long double b)
-{
- return -f3_cmp(b, a);
-}
diff --git a/tinycc/lib/libtcc1.c b/tinycc/lib/libtcc1.c
deleted file mode 100644
index ae94af1..0000000
--- a/tinycc/lib/libtcc1.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/* TCC runtime library.
- Parts of this code are (c) 2002 Fabrice Bellard
-
- Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
-
-This file is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file into combinations with other programs,
-and to distribute those combinations without any restriction coming
-from the use of this file. (The General Public License restrictions
-do apply in other respects; for example, they cover modification of
-the file, and distribution when not linked into a combine
-executable.)
-
-This file is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
-*/
-
-#define W_TYPE_SIZE 32
-#define BITS_PER_UNIT 8
-
-typedef int Wtype;
-typedef unsigned int UWtype;
-typedef unsigned int USItype;
-typedef long long DWtype;
-typedef unsigned long long UDWtype;
-
-struct DWstruct {
- Wtype low, high;
-};
-
-typedef union
-{
- struct DWstruct s;
- DWtype ll;
-} DWunion;
-
-typedef long double XFtype;
-#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
-#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
-
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS 126
-#define SIGNBIT 0x80000000
-#define HIDDEN (1 << 23)
-#define SIGN(fp) ((fp) & SIGNBIT)
-#define EXP(fp) (((fp) >> 23) & 0xFF)
-#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
-#define PACK(s,e,m) ((s) | ((e) << 23) | (m))
-
-/* the following deal with IEEE double-precision numbers */
-#define EXCESSD 1022
-#define HIDDEND (1 << 20)
-#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
-#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
-#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
- (fp.l.lower >> 22))
-#define HIDDEND_LL ((long long)1 << 52)
-#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
-#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
-
-/* the following deal with x86 long double-precision numbers */
-#define EXCESSLD 16382
-#define EXPLD(fp) (fp.l.upper & 0x7fff)
-#define SIGNLD(fp) ((fp.l.upper) & 0x8000)
-
-/* only for x86 */
-union ldouble_long {
- long double ld;
- struct {
- unsigned long long lower;
- unsigned short upper;
- } l;
-};
-
-union double_long {
- double d;
-#if 1
- struct {
- unsigned int lower;
- int upper;
- } l;
-#else
- struct {
- int upper;
- unsigned int lower;
- } l;
-#endif
- long long ll;
-};
-
-union float_long {
- float f;
- unsigned int l;
-};
-
-/* XXX: we don't support several builtin supports for now */
-#if !defined __x86_64__ && !defined __arm__
-
-/* XXX: use gcc/tcc intrinsic ? */
-#if defined __i386__
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subl %5,%1\n\tsbbl %3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "0" ((USItype) (ah)), \
- "g" ((USItype) (bh)), \
- "1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("mull %3" \
- : "=a" ((USItype) (w0)), \
- "=d" ((USItype) (w1)) \
- : "%0" ((USItype) (u)), \
- "rm" ((USItype) (v)))
-#define udiv_qrnnd(q, r, n1, n0, dv) \
- __asm__ ("divl %4" \
- : "=a" ((USItype) (q)), \
- "=d" ((USItype) (r)) \
- : "0" ((USItype) (n0)), \
- "1" ((USItype) (n1)), \
- "rm" ((USItype) (dv)))
-#define count_leading_zeros(count, x) \
- do { \
- USItype __cbtmp; \
- __asm__ ("bsrl %1,%0" \
- : "=r" (__cbtmp) : "rm" ((USItype) (x))); \
- (count) = __cbtmp ^ 31; \
- } while (0)
-#else
-#error unsupported CPU type
-#endif
-
-/* most of this code is taken from libgcc2.c from gcc */
-
-static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
-{
- DWunion ww;
- DWunion nn, dd;
- DWunion rr;
- UWtype d0, d1, n0, n1, n2;
- UWtype q0, q1;
- UWtype b, bm;
-
- nn.ll = n;
- dd.ll = d;
-
- d0 = dd.s.low;
- d1 = dd.s.high;
- n0 = nn.s.low;
- n1 = nn.s.high;
-
-#if !defined(UDIV_NEEDS_NORMALIZATION)
- if (d1 == 0)
- {
- if (d0 > n1)
- {
- /* 0q = nn / 0D */
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
- q1 = 0;
-
- /* Remainder in n0. */
- }
- else
- {
- /* qq = NN / 0d */
-
- if (d0 == 0)
- d0 = 1 / d0; /* Divide intentionally by zero. */
-
- udiv_qrnnd (q1, n1, 0, n1, d0);
- udiv_qrnnd (q0, n0, n1, n0, d0);
-
- /* Remainder in n0. */
- }
-
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = 0;
- *rp = rr.ll;
- }
- }
-
-#else /* UDIV_NEEDS_NORMALIZATION */
-
- if (d1 == 0)
- {
- if (d0 > n1)
- {
- /* 0q = nn / 0D */
-
- count_leading_zeros (bm, d0);
-
- if (bm != 0)
- {
- /* Normalize, i.e. make the most significant bit of the
- denominator set. */
-
- d0 = d0 << bm;
- n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
- n0 = n0 << bm;
- }
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
- q1 = 0;
-
- /* Remainder in n0 >> bm. */
- }
- else
- {
- /* qq = NN / 0d */
-
- if (d0 == 0)
- d0 = 1 / d0; /* Divide intentionally by zero. */
-
- count_leading_zeros (bm, d0);
-
- if (bm == 0)
- {
- /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
- conclude (the most significant bit of n1 is set) /\ (the
- leading quotient digit q1 = 1).
-
- This special case is necessary, not an optimization.
- (Shifts counts of W_TYPE_SIZE are undefined.) */
-
- n1 -= d0;
- q1 = 1;
- }
- else
- {
- /* Normalize. */
-
- b = W_TYPE_SIZE - bm;
-
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd (q1, n1, n2, n1, d0);
- }
-
- /* n1 != d0... */
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
-
- /* Remainder in n0 >> bm. */
- }
-
- if (rp != 0)
- {
- rr.s.low = n0 >> bm;
- rr.s.high = 0;
- *rp = rr.ll;
- }
- }
-#endif /* UDIV_NEEDS_NORMALIZATION */
-
- else
- {
- if (d1 > n1)
- {
- /* 00 = nn / DD */
-
- q0 = 0;
- q1 = 0;
-
- /* Remainder in n1n0. */
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- }
- else
- {
- /* 0q = NN / dd */
-
- count_leading_zeros (bm, d1);
- if (bm == 0)
- {
- /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
- conclude (the most significant bit of n1 is set) /\ (the
- quotient digit q0 = 0 or 1).
-
- This special case is necessary, not an optimization. */
-
- /* The condition on the next line takes advantage of that
- n1 >= d1 (true due to program flow). */
- if (n1 > d1 || n0 >= d0)
- {
- q0 = 1;
- sub_ddmmss (n1, n0, n1, n0, d1, d0);
- }
- else
- q0 = 0;
-
- q1 = 0;
-
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- }
- else
- {
- UWtype m1, m0;
- /* Normalize. */
-
- b = W_TYPE_SIZE - bm;
-
- d1 = (d1 << bm) | (d0 >> b);
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd (q0, n1, n2, n1, d1);
- umul_ppmm (m1, m0, q0, d0);
-
- if (m1 > n1 || (m1 == n1 && m0 > n0))
- {
- q0--;
- sub_ddmmss (m1, m0, m1, m0, d1, d0);
- }
-
- q1 = 0;
-
- /* Remainder in (n1n0 - m1m0) >> bm. */
- if (rp != 0)
- {
- sub_ddmmss (n1, n0, n1, n0, m1, m0);
- rr.s.low = (n1 << b) | (n0 >> bm);
- rr.s.high = n1 >> bm;
- *rp = rr.ll;
- }
- }
- }
- }
-
- ww.s.low = q0;
- ww.s.high = q1;
- return ww.ll;
-}
-
-#define __negdi2(a) (-(a))
-
-long long __divdi3(long long u, long long v)
-{
- int c = 0;
- DWunion uu, vv;
- DWtype w;
-
- uu.ll = u;
- vv.ll = v;
-
- if (uu.s.high < 0) {
- c = ~c;
- uu.ll = __negdi2 (uu.ll);
- }
- if (vv.s.high < 0) {
- c = ~c;
- vv.ll = __negdi2 (vv.ll);
- }
- w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
- if (c)
- w = __negdi2 (w);
- return w;
-}
-
-long long __moddi3(long long u, long long v)
-{
- int c = 0;
- DWunion uu, vv;
- DWtype w;
-
- uu.ll = u;
- vv.ll = v;
-
- if (uu.s.high < 0) {
- c = ~c;
- uu.ll = __negdi2 (uu.ll);
- }
- if (vv.s.high < 0)
- vv.ll = __negdi2 (vv.ll);
-
- __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
- if (c)
- w = __negdi2 (w);
- return w;
-}
-
-unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
-{
- return __udivmoddi4 (u, v, (UDWtype *) 0);
-}
-
-unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
-{
- UDWtype w;
-
- __udivmoddi4 (u, v, &w);
- return w;
-}
-
-/* XXX: fix tcc's code generator to do this instead */
-long long __ashrdi3(long long a, int b)
-{
-#ifdef __TINYC__
- DWunion u;
- u.ll = a;
- if (b >= 32) {
- u.s.low = u.s.high >> (b - 32);
- u.s.high = u.s.high >> 31;
- } else if (b != 0) {
- u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
- u.s.high = u.s.high >> b;
- }
- return u.ll;
-#else
- return a >> b;
-#endif
-}
-
-/* XXX: fix tcc's code generator to do this instead */
-unsigned long long __lshrdi3(unsigned long long a, int b)
-{
-#ifdef __TINYC__
- DWunion u;
- u.ll = a;
- if (b >= 32) {
- u.s.low = (unsigned)u.s.high >> (b - 32);
- u.s.high = 0;
- } else if (b != 0) {
- u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
- u.s.high = (unsigned)u.s.high >> b;
- }
- return u.ll;
-#else
- return a >> b;
-#endif
-}
-
-/* XXX: fix tcc's code generator to do this instead */
-long long __ashldi3(long long a, int b)
-{
-#ifdef __TINYC__
- DWunion u;
- u.ll = a;
- if (b >= 32) {
- u.s.high = (unsigned)u.s.low << (b - 32);
- u.s.low = 0;
- } else if (b != 0) {
- u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
- u.s.low = (unsigned)u.s.low << b;
- }
- return u.ll;
-#else
- return a << b;
-#endif
-}
-
-#endif /* !__x86_64__ */
-
-/* XXX: fix tcc's code generator to do this instead */
-float __floatundisf(unsigned long long a)
-{
- DWunion uu;
- XFtype r;
-
- uu.ll = a;
- if (uu.s.high >= 0) {
- return (float)uu.ll;
- } else {
- r = (XFtype)uu.ll;
- r += 18446744073709551616.0;
- return (float)r;
- }
-}
-
-double __floatundidf(unsigned long long a)
-{
- DWunion uu;
- XFtype r;
-
- uu.ll = a;
- if (uu.s.high >= 0) {
- return (double)uu.ll;
- } else {
- r = (XFtype)uu.ll;
- r += 18446744073709551616.0;
- return (double)r;
- }
-}
-
-long double __floatundixf(unsigned long long a)
-{
- DWunion uu;
- XFtype r;
-
- uu.ll = a;
- if (uu.s.high >= 0) {
- return (long double)uu.ll;
- } else {
- r = (XFtype)uu.ll;
- r += 18446744073709551616.0;
- return (long double)r;
- }
-}
-
-unsigned long long __fixunssfdi (float a1)
-{
- register union float_long fl1;
- register int exp;
- register unsigned long long l;
-
- fl1.f = a1;
-
- if (fl1.l == 0)
- return (0);
-
- exp = EXP (fl1.l) - EXCESS - 24;
- l = MANT(fl1.l);
-
- if (exp >= 41)
- return 1ULL << 63;
- else if (exp >= 0)
- l <<= exp;
- else if (exp >= -23)
- l >>= -exp;
- else
- return 0;
- if (SIGN(fl1.l))
- l = (unsigned long long)-l;
- return l;
-}
-
-long long __fixsfdi (float a1)
-{
- long long ret; int s;
- ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
- return s ? ret : -ret;
-}
-
-unsigned long long __fixunsdfdi (double a1)
-{
- register union double_long dl1;
- register int exp;
- register unsigned long long l;
-
- dl1.d = a1;
-
- if (dl1.ll == 0)
- return (0);
-
- exp = EXPD (dl1) - EXCESSD - 53;
- l = MANTD_LL(dl1);
-
- if (exp >= 12)
- return 1ULL << 63; /* overflow result (like gcc, somewhat) */
- else if (exp >= 0)
- l <<= exp;
- else if (exp >= -52)
- l >>= -exp;
- else
- return 0;
- if (SIGND(dl1))
- l = (unsigned long long)-l;
- return l;
-}
-
-long long __fixdfdi (double a1)
-{
- long long ret; int s;
- ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
- return s ? ret : -ret;
-}
-
-#ifndef __arm__
-unsigned long long __fixunsxfdi (long double a1)
-{
- register union ldouble_long dl1;
- register int exp;
- register unsigned long long l;
-
- dl1.ld = a1;
-
- if (dl1.l.lower == 0 && dl1.l.upper == 0)
- return (0);
-
- exp = EXPLD (dl1) - EXCESSLD - 64;
- l = dl1.l.lower;
- if (exp > 0)
- return 1ULL << 63;
- if (exp < -63)
- return 0;
- l >>= -exp;
- if (SIGNLD(dl1))
- l = (unsigned long long)-l;
- return l;
-}
-
-long long __fixxfdi (long double a1)
-{
- long long ret; int s;
- ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
- return s ? ret : -ret;
-}
-#endif /* !ARM */
-
-#if defined __x86_64__
-/* float constants used for unary minus operation */
-const float __mzerosf = -0.0;
-const double __mzerodf = -0.0;
-#endif
-
-#if defined _WIN64
-/* MSVC x64 intrinsic */
-void __faststorefence(void)
-{
- __asm__("lock; orl $0,(%rsp)");
-}
-#endif
diff --git a/tinycc/lib/stdatomic.c b/tinycc/lib/stdatomic.c
deleted file mode 100644
index bd8c0ce..0000000
--- a/tinycc/lib/stdatomic.c
+++ /dev/null
@@ -1,166 +0,0 @@
-// for libtcc1, avoid including files that are not part of tcc
-// #include <stdint.h>
-#define uint8_t unsigned char
-#define uint16_t unsigned short
-#define uint32_t unsigned int
-#define uint64_t unsigned long long
-#define bool _Bool
-#define false 0
-#define true 1
-#define __ATOMIC_RELAXED 0
-#define __ATOMIC_CONSUME 1
-#define __ATOMIC_ACQUIRE 2
-#define __ATOMIC_RELEASE 3
-#define __ATOMIC_ACQ_REL 4
-#define __ATOMIC_SEQ_CST 5
-typedef __SIZE_TYPE__ size_t;
-
-#if defined __i386__ || defined __x86_64__
-#define ATOMIC_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \
- bool __atomic_compare_exchange_##MODE \
- (volatile void *atom, void *ref, TYPE xchg, \
- bool weak, int success_memorder, int failure_memorder) \
- { \
- TYPE rv; \
- TYPE cmp = *(TYPE *)ref; \
- __asm__ volatile( \
- "lock cmpxchg" SUFFIX " %2,%1\n" \
- : "=a" (rv), "+m" (*(TYPE *)atom) \
- : "q" (xchg), "0" (cmp) \
- : "memory" \
- ); \
- *(TYPE *)ref = rv; \
- return (rv == cmp); \
- }
-#else
-#define ATOMIC_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \
- extern bool __atomic_compare_exchange_##MODE \
- (volatile void *atom, void *ref, TYPE xchg, \
- bool weak, int success_memorder, int failure_memorder);
-#endif
-
-#define ATOMIC_LOAD(TYPE, MODE) \
- TYPE __atomic_load_##MODE(const volatile void *atom, int memorder) \
- { \
- return *(volatile TYPE *)atom; \
- }
-
-#define ATOMIC_STORE(TYPE, MODE) \
- void __atomic_store_##MODE(volatile void *atom, TYPE value, int memorder) \
- { \
- *(volatile TYPE *)atom = value; \
- }
-
-#define ATOMIC_GEN_OP(TYPE, MODE, NAME, OP, RET) \
- TYPE __atomic_##NAME##_##MODE(volatile void *atom, TYPE value, int memorder) \
- { \
- TYPE xchg, cmp; \
- __atomic_load((TYPE *)atom, (TYPE *)&cmp, __ATOMIC_RELAXED); \
- do { \
- xchg = (OP); \
- } while (!__atomic_compare_exchange((TYPE *)atom, &cmp, &xchg, true, \
- __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \
- return RET; \
- }
-
-#define ATOMIC_EXCHANGE(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, exchange, value, cmp)
-#define ATOMIC_ADD_FETCH(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, add_fetch, (cmp + value), xchg)
-#define ATOMIC_SUB_FETCH(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, sub_fetch, (cmp - value), xchg)
-#define ATOMIC_AND_FETCH(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, and_fetch, (cmp & value), xchg)
-#define ATOMIC_OR_FETCH(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, or_fetch, (cmp | value), xchg)
-#define ATOMIC_XOR_FETCH(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, xor_fetch, (cmp ^ value), xchg)
-#define ATOMIC_NAND_FETCH(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, nand_fetch, ~(cmp & value), xchg)
-#define ATOMIC_FETCH_ADD(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, fetch_add, (cmp + value), cmp)
-#define ATOMIC_FETCH_SUB(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, fetch_sub, (cmp - value), cmp)
-#define ATOMIC_FETCH_AND(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, fetch_and, (cmp & value), cmp)
-#define ATOMIC_FETCH_OR(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, fetch_or, (cmp | value), cmp)
-#define ATOMIC_FETCH_XOR(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, fetch_xor, (cmp ^ value), cmp)
-#define ATOMIC_FETCH_NAND(TYPE, MODE) \
- ATOMIC_GEN_OP(TYPE, MODE, fetch_nand, ~(cmp & value), cmp)
-
-#define ATOMIC_GEN(TYPE, SIZE, SUFFIX) \
- ATOMIC_STORE(TYPE, SIZE) \
- ATOMIC_LOAD(TYPE, SIZE) \
- ATOMIC_COMPARE_EXCHANGE(TYPE, SIZE, SUFFIX) \
- ATOMIC_EXCHANGE(TYPE, SIZE) \
- ATOMIC_ADD_FETCH(TYPE, SIZE) \
- ATOMIC_SUB_FETCH(TYPE, SIZE) \
- ATOMIC_AND_FETCH(TYPE, SIZE) \
- ATOMIC_OR_FETCH(TYPE, SIZE) \
- ATOMIC_XOR_FETCH(TYPE, SIZE) \
- ATOMIC_NAND_FETCH(TYPE, SIZE) \
- ATOMIC_FETCH_ADD(TYPE, SIZE) \
- ATOMIC_FETCH_SUB(TYPE, SIZE) \
- ATOMIC_FETCH_AND(TYPE, SIZE) \
- ATOMIC_FETCH_OR(TYPE, SIZE) \
- ATOMIC_FETCH_XOR(TYPE, SIZE) \
- ATOMIC_FETCH_NAND(TYPE, SIZE)
-
-ATOMIC_GEN(uint8_t, 1, "b")
-ATOMIC_GEN(uint16_t, 2, "w")
-ATOMIC_GEN(uint32_t, 4, "l")
-#if defined __x86_64__ || defined __aarch64__ || defined __riscv
-ATOMIC_GEN(uint64_t, 8, "q")
-#endif
-
-/* uses alias to allow building with gcc/clang */
-#ifdef __TINYC__
-#define ATOMIC(x) __atomic_##x
-#else
-#define ATOMIC(x) __tcc_atomic_##x
-#endif
-
-void ATOMIC(signal_fence) (int memorder)
-{
-}
-
-void ATOMIC(thread_fence) (int memorder)
-{
-#if defined __i386__
- __asm__ volatile("lock orl $0, (%esp)");
-#elif defined __x86_64__
- __asm__ volatile("lock orq $0, (%rsp)");
-#elif defined __arm__
- __asm__ volatile(".int 0xee070fba"); // mcr p15, 0, r0, c7, c10, 5
-#elif defined __aarch64__
- __asm__ volatile(".int 0xd5033bbf"); // dmb ish
-#elif defined __riscv
- __asm__ volatile(".int 0x0ff0000f"); // fence iorw,iorw
-#endif
-}
-
-bool ATOMIC(is_lock_free) (unsigned long size, const volatile void *ptr)
-{
- bool ret;
-
- switch (size) {
- case 1: ret = true; break;
- case 2: ret = true; break;
- case 4: ret = true; break;
-#if defined __x86_64__ || defined __aarch64__ || defined __riscv
- case 8: ret = true; break;
-#else
- case 8: ret = false; break;
-#endif
- default: ret = false; break;
- }
- return ret;
-}
-
-#ifndef __TINYC__
-void __atomic_signal_fence(int memorder) __attribute__((alias("__tcc_atomic_signal_fence")));
-void __atomic_thread_fence(int memorder) __attribute__((alias("__tcc_atomic_thread_fence")));
-bool __atomic_is_lock_free(unsigned long size, const volatile void *ptr) __attribute__((alias("__tcc_atomic_is_lock_free")));
-#endif
diff --git a/tinycc/lib/tcov.c b/tinycc/lib/tcov.c
deleted file mode 100644
index 32b7d18..0000000
--- a/tinycc/lib/tcov.c
+++ /dev/null
@@ -1,428 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#ifndef _WIN32
-#include <unistd.h>
-#include <errno.h>
-#else
-#include <windows.h>
-#include <io.h>
-#endif
-
-/* section layout (all little endian):
- 32bit offset to executable/so file name
- filename \0
- function name \0
- align to 64 bits
- 64bit function start line
- 64bits end_line(28bits) / start_line(28bits) / flag=0xff(8bits)
- 64bits counter
- \0
- \0
- \0
- executable/so file name \0
- */
-
-typedef struct tcov_line {
- unsigned int fline;
- unsigned int lline;
- unsigned long long count;
-} tcov_line;
-
-typedef struct tcov_function {
- char *function;
- unsigned int first_line;
- unsigned int n_line;
- unsigned int m_line;
- tcov_line *line;
-} tcov_function;
-
-typedef struct tcov_file {
- char *filename;
- unsigned int n_func;
- unsigned int m_func;
- tcov_function *func;
- struct tcov_file *next;
-} tcov_file;
-
-static FILE *open_tcov_file (char *cov_filename)
-{
- int fd;
-#ifndef _WIN32
- struct flock lock;
-
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0; /* Until EOF. */
- lock.l_pid = getpid ();
-#endif
- fd = open (cov_filename, O_RDWR | O_CREAT, 0666);
- if (fd < 0)
- return NULL;
-
-#ifndef _WIN32
- while (fcntl (fd, F_SETLKW, &lock) && errno == EINTR)
- continue;
-#else
- {
- OVERLAPPED overlapped = { 0 };
- LockFileEx((HANDLE)_get_osfhandle(fd), LOCKFILE_EXCLUSIVE_LOCK,
- 0, 1, 0, &overlapped);
- }
-#endif
-
- return fdopen (fd, "r+");
-}
-
-static unsigned long long get_value(unsigned char *p, int size)
-{
- unsigned long long value = 0;
-
- p += size;
- while (size--)
- value = (value << 8) | *--p;
- return value;
-}
-
-static int sort_func (const void *p, const void *q)
-{
- const tcov_function *pp = (const tcov_function *) p;
- const tcov_function *pq = (const tcov_function *) q;
-
- return pp->first_line > pq->first_line ? 1 :
- pp->first_line < pq->first_line ? -1 : 0;
-}
-
-static int sort_line (const void *p, const void *q)
-{
- const tcov_line *pp = (const tcov_line *) p;
- const tcov_line *pq = (const tcov_line *) q;
-
- return pp->fline > pq->fline ? 1 :
- pp->fline < pq->fline ? -1 :
- pp->count < pq->count ? 1 :
- pp->count > pq->count ? -1 : 0;
-}
-
-/* sort to let inline functions work */
-static tcov_file *sort_test_coverage (unsigned char *p)
-{
- int i, j, k;
- unsigned char *start = p;
- tcov_file *file = NULL;
- tcov_file *nfile;
-
- p += 4;
- while (*p) {
- char *filename = (char *)p;
- size_t len = strlen (filename);
-
- nfile = file;
- while (nfile) {
- if (strcmp (nfile->filename, filename) == 0)
- break;
- nfile = nfile->next;
- }
- if (nfile == NULL) {
- nfile = malloc (sizeof(tcov_file));
- if (nfile == NULL) {
- fprintf (stderr, "Malloc error test_coverage\n");
- return file;
- }
- nfile->filename = filename;
- nfile->n_func = 0;
- nfile->m_func = 0;
- nfile->func = NULL;
- nfile->next = NULL;
- if (file == NULL)
- file = nfile;
- else {
- tcov_file *lfile = file;
-
- while (lfile->next)
- lfile = lfile->next;
- lfile->next = nfile;
- }
- }
- p += len + 1;
- while (*p) {
- int i;
- char *function = (char *)p;
- tcov_function *func;
-
- p += strlen (function) + 1;
- p += -(p - start) & 7;
- for (i = 0; i < nfile->n_func; i++) {
- func = &nfile->func[i];
- if (strcmp (func->function, function) == 0)
- break;
- }
- if (i == nfile->n_func) {
- if (nfile->n_func >= nfile->m_func) {
- nfile->m_func = nfile->m_func == 0 ? 4 : nfile->m_func * 2;
- nfile->func = realloc (nfile->func,
- nfile->m_func *
- sizeof (tcov_function));
- if (nfile->func == NULL) {
- fprintf (stderr, "Realloc error test_coverage\n");
- return file;
- }
- }
- func = &nfile->func[nfile->n_func++];
- func->function = function;
- func->first_line = get_value (p, 8);
- func->n_line = 0;
- func->m_line = 0;
- func->line = NULL;
- }
- p += 8;
- while (*p) {
- tcov_line *line;
- unsigned long long val;
-
- if (func->n_line >= func->m_line) {
- func->m_line = func->m_line == 0 ? 4 : func->m_line * 2;
- func->line = realloc (func->line,
- func->m_line * sizeof (tcov_line));
- if (func->line == NULL) {
- fprintf (stderr, "Realloc error test_coverage\n");
- return file;
- }
- }
- line = &func->line[func->n_line++];
- val = get_value (p, 8);
- line->fline = (val >> 8) & 0xfffffffULL;
- line->lline = val >> 36;
- line->count = get_value (p + 8, 8);
- p += 16;
- }
- p++;
- }
- p++;
- }
- nfile = file;
- while (nfile) {
- qsort (nfile->func, nfile->n_func, sizeof (tcov_function), sort_func);
- for (i = 0; i < nfile->n_func; i++) {
- tcov_function *func = &nfile->func[i];
- qsort (func->line, func->n_line, sizeof (tcov_line), sort_line);
- }
- nfile = nfile->next;
- }
- return file;
-}
-
-/* merge with previous tcov file */
-static void merge_test_coverage (tcov_file *file, FILE *fp,
- unsigned int *pruns)
-{
- unsigned int runs;
- char *p;
- char str[10000];
-
- *pruns = 1;
- if (fp == NULL)
- return;
- if (fgets(str, sizeof(str), fp) &&
- (p = strrchr (str, ':')) &&
- (sscanf (p + 1, "%u", &runs) == 1))
- *pruns = runs + 1;
- while (file) {
- int i;
- size_t len = strlen (file->filename);
-
- while (fgets(str, sizeof(str), fp) &&
- (p = strstr(str, "0:File:")) == NULL) {}
- if ((p = strstr(str, "0:File:")) == NULL ||
- strncmp (p + strlen("0:File:"), file->filename, len) != 0 ||
- p[strlen("0:File:") + len] != ' ')
- break;
- for (i = 0; i < file->n_func; i++) {
- int j;
- tcov_function *func = &file->func[i];
- unsigned int next_zero = 0;
- unsigned int curline = 0;
-
- for (j = 0; j < func->n_line; j++) {
- tcov_line *line = &func->line[j];
- unsigned int fline = line->fline;
- unsigned long long count;
- unsigned int tmp;
- char c;
-
- while (curline < fline &&
- fgets(str, sizeof(str), fp))
- if ((p = strchr(str, ':')) &&
- sscanf (p + 1, "%u", &tmp) == 1)
- curline = tmp;
- if (sscanf (str, "%llu%c\n", &count, &c) == 2) {
- if (next_zero == 0)
- line->count += count;
- next_zero = c == '*';
- }
- }
- }
- file = file->next;
- }
-}
-
-/* store tcov data in file */
-void __store_test_coverage (unsigned char * p)
-{
- int i, j;
- unsigned int files;
- unsigned int funcs;
- unsigned int blocks;
- unsigned int blocks_run;
- unsigned int runs;
- char *cov_filename = (char *)p + get_value (p, 4);
- FILE *fp;
- char *q;
- tcov_file *file;
- tcov_file *nfile;
- tcov_function *func;
-
- fp = open_tcov_file (cov_filename);
- if (fp == NULL) {
- fprintf (stderr, "Cannot create coverage file: %s\n", cov_filename);
- return;
- }
- file = sort_test_coverage (p);
- merge_test_coverage (file, fp, &runs);
- fseek (fp, 0, SEEK_SET);
- fprintf (fp, " -: 0:Runs:%u\n", runs);
- files = 0;
- funcs = 0;
- blocks = 0;
- blocks_run = 0;
- nfile = file;
- while (nfile) {
- files++;
- for (i = 0; i < nfile->n_func; i++) {
- func = &nfile->func[i];
- funcs++;
- for (j = 0; j < func->n_line; j++) {
- blocks++;
- blocks_run += func->line[j].count != 0;
- }
- }
- nfile = nfile->next;
- }
- if (blocks == 0)
- blocks = 1;
- fprintf (fp, " -: 0:All:%s Files:%u Functions:%u %.02f%%\n",
- cov_filename, files, funcs, 100.0 * (double) blocks_run / blocks);
- nfile = file;
- while (nfile) {
- FILE *src = fopen (nfile->filename, "r");
- unsigned int curline = 1;
- char str[10000];
-
- if (src == NULL)
- goto next;
- funcs = 0;
- blocks = 0;
- blocks_run = 0;
- for (i = 0; i < nfile->n_func; i++) {
- func = &nfile->func[i];
- funcs++;
- for (j = 0; j < func->n_line; j++) {
- blocks++;
- blocks_run += func->line[j].count != 0;
- }
- }
- if (blocks == 0)
- blocks = 1;
- fprintf (fp, " -: 0:File:%s Functions:%u %.02f%%\n",
- nfile->filename, funcs, 100.0 * (double) blocks_run / blocks);
- for (i = 0; i < nfile->n_func; i++) {
- func = &nfile->func[i];
-
- while (curline < func->first_line)
- if (fgets(str, sizeof(str), src))
- fprintf (fp, " -:%5u:%s", curline++, str);
- blocks = 0;
- blocks_run = 0;
- for (j = 0; j < func->n_line; j++) {
- blocks++;
- blocks_run += func->line[j].count != 0;
- }
- if (blocks == 0)
- blocks = 1;
- fprintf (fp, " -: 0:Function:%s %.02f%%\n",
- func->function, 100.0 * (double) blocks_run / blocks);
-#if 0
- for (j = 0; j < func->n_line; j++) {
- unsigned int fline = func->line[j].fline;
- unsigned int lline = func->line[j].lline;
- unsigned long long count = func->line[j].count;
-
- fprintf (fp, "%u %u %llu\n", fline, lline, count);
- }
-#endif
- for (j = 0; j < func->n_line;) {
- unsigned int fline = func->line[j].fline;
- unsigned int lline = func->line[j].lline;
- unsigned long long count = func->line[j].count;
- unsigned int has_zero = 0;
- unsigned int same_line = fline == lline;
-
- j++;
- while (j < func->n_line) {
- unsigned int nfline = func->line[j].fline;
- unsigned int nlline = func->line[j].lline;
- unsigned long long ncount = func->line[j].count;
-
- if (fline == nfline) {
- if (ncount == 0)
- has_zero = 1;
- else if (ncount > count)
- count = ncount;
- same_line = nfline == nlline;
- lline = nlline;
- j++;
- }
- else
- break;
- }
- if (same_line)
- lline++;
-
- while (curline < fline)
- if (fgets(str, sizeof(str), src))
- fprintf (fp, " -:%5u:%s", curline++, str);
- while (curline < lline &&
- fgets(str, sizeof(str), src)) {
- if (count == 0)
- fprintf (fp, " #####:%5u:%s",
- curline, str);
- else if (has_zero)
- fprintf (fp, "%8llu*:%5u:%s",
- count, curline, str);
- else
- fprintf (fp, "%9llu:%5u:%s",
- count, curline, str);
- curline++;
- }
- }
- }
- while (fgets(str, sizeof(str), src))
- fprintf (fp, " -:%5u:%s", curline++, str);
- fclose (src);
-next:
- nfile = nfile->next;
- }
- while (file) {
- for (i = 0; i < file->n_func; i++) {
- func = &file->func[i];
- free (func->line);
- }
- free (file->func);
- nfile = file;
- file = file->next;
- free (nfile);
- }
- fclose (fp);
-}
diff --git a/tinycc/lib/va_list.c b/tinycc/lib/va_list.c
deleted file mode 100644
index 1fb5512..0000000
--- a/tinycc/lib/va_list.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* va_list.c - tinycc support for va_list on X86_64 */
-
-#if defined __x86_64__
-
-/* Avoid include files, they may not be available when cross compiling */
-extern void abort(void);
-
-/* This should be in sync with our include/stdarg.h */
-enum __va_arg_type {
- __va_gen_reg, __va_float_reg, __va_stack
-};
-
-/* GCC compatible definition of va_list. */
-/*predefined by TCC (tcc_predefs.h):
-typedef struct {
- unsigned int gp_offset;
- unsigned int fp_offset;
- union {
- unsigned int overflow_offset;
- char *overflow_arg_area;
- };
- char *reg_save_area;
-} __builtin_va_list[1];
-*/
-
-extern void *memcpy(void *dest, const void *src, unsigned long n);
-
-void *__va_arg(__builtin_va_list ap,
- int arg_type,
- int size, int align)
-{
- size = (size + 7) & ~7;
- align = (align + 7) & ~7;
- switch ((enum __va_arg_type)arg_type) {
- case __va_gen_reg:
- if (ap->gp_offset + size <= 48) {
- ap->gp_offset += size;
- return ap->reg_save_area + ap->gp_offset - size;
- }
- goto use_overflow_area;
-
- case __va_float_reg:
- if (ap->fp_offset < 128 + 48) {
- ap->fp_offset += 16;
- if (size == 8)
- return ap->reg_save_area + ap->fp_offset - 16;
- if (ap->fp_offset < 128 + 48) {
- memcpy(ap->reg_save_area + ap->fp_offset - 8,
- ap->reg_save_area + ap->fp_offset, 8);
- ap->fp_offset += 16;
- return ap->reg_save_area + ap->fp_offset - 32;
- }
- }
- goto use_overflow_area;
-
- case __va_stack:
- use_overflow_area:
- ap->overflow_arg_area += size;
- ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
- return ap->overflow_arg_area - size;
-
- default: /* should never happen */
- abort();
- return 0;
- }
-}
-#endif