diff options
| author | Uneven Prankster <unevenprankster@protonmail.com> | 2023-10-15 21:28:29 -0300 |
|---|---|---|
| committer | Uneven Prankster <unevenprankster@protonmail.com> | 2023-10-15 21:28:29 -0300 |
| commit | 1c0cc775732201f4c4d3ee0d6772be786b3b4aa1 (patch) | |
| tree | f5d692d046868261275c7430a624c3ea9ed75d3d /tinycc/lib | |
| parent | a89f892640cf12f75c7ce18e6e88c70a8d3965ed (diff) | |
A lot has certainly happened!
Diffstat (limited to 'tinycc/lib')
| -rw-r--r-- | tinycc/lib/Makefile | 94 | ||||
| -rw-r--r-- | tinycc/lib/alloca-bt.S | 96 | ||||
| -rw-r--r-- | tinycc/lib/alloca.S | 85 | ||||
| -rw-r--r-- | tinycc/lib/armeabi.c | 544 | ||||
| -rw-r--r-- | tinycc/lib/armflush.c | 51 | ||||
| -rw-r--r-- | tinycc/lib/atomic.S | 858 | ||||
| -rw-r--r-- | tinycc/lib/bcheck.c | 2270 | ||||
| -rw-r--r-- | tinycc/lib/bt-dll.c | 74 | ||||
| -rw-r--r-- | tinycc/lib/bt-exe.c | 74 | ||||
| -rw-r--r-- | tinycc/lib/bt-log.c | 47 | ||||
| -rw-r--r-- | tinycc/lib/builtin.c | 164 | ||||
| -rw-r--r-- | tinycc/lib/dsohandle.c | 1 | ||||
| -rw-r--r-- | tinycc/lib/lib-arm64.c | 677 | ||||
| -rw-r--r-- | tinycc/lib/libtcc1.c | 641 | ||||
| -rw-r--r-- | tinycc/lib/stdatomic.c | 166 | ||||
| -rw-r--r-- | tinycc/lib/tcov.c | 428 | ||||
| -rw-r--r-- | tinycc/lib/va_list.c | 67 |
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 |
