- revert Makefiles to state before last bcheck additions Instead, just load bcheck.o explicitly if that is what is wanted. - move tcc_add_bcheck() to the <target>-link.c files and remove revently added arguments. This function is to support tccelf.c with linking, not for tccgen.c to support compilation. - remove -ba option: It said: "-ba Enable better address checking with bounds checker" Okay, if it is better then to have it is not an option. - remove va_copy. It is C99 and we try to stay C89 in tinycc when possible. For example, MS compilers do not have va_copy. - win64: revert any 'fixes' to alloca It was correct as it was before, except for bound_checking where it was not implemented. This should now work too. - remove parasitic filename:linenum features Such feature is already present with rt_printline in tccrun.c. If it doesn't work it can be fixed. - revert changes to gen_bounded_ptr_add() gen_bounded_ptr_add() was working as it should before (mostly). For the sake of simplicity I switched it to CDECL. Anyway, FASTCALL means SLOWCALL with tinycc. In exchange you get one addition which is required for bounds_cnecking function arguments. The important thing is to check them *BEFORE* they are loaded into registers. New function gbound_args() does that. In any case, code instrumentation with the bounds-check functions as such now seems to work flawlessly again, which means when they are inserted as NOPs, any code that tcc can compile, seems to behave just the same as without them. What these functions then do when fully enabled, is a differnt story. I did not touch this.
Showing the changes to lib (5 of 19 files). Show all
Unified · Split
| @@ -7,8 +7,6 @@ include $(TOP)/Makefile · 6 unmodified lines | |||
| 7 | VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib | 7 | VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib |
| 8 | T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown) | 8 | T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown) |
| 9 | X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-) | 9 | X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-) |
| 10 | BIN = $(TOP)/$(X)libtcc1.a | ||
| 11 | BINB = $(TOP)/$(X)libtccb1.a | ||
| 12 | 10 | ||
| 13 | XTCC ?= $(TOP)/$(X)tcc$(EXESUF) | 11 | XTCC ?= $(TOP)/$(X)tcc$(EXESUF) |
| 14 | XCC = $(XTCC) | 12 | XCC = $(XTCC) |
| @@ -20,8 +18,6 @@ XCFG = $(or $(findstring -win,$T),-unx) · 5 unmodified lines | |||
| 20 | 18 | ||
| 21 | # in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes | 19 | # in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes |
| 22 | arm-libtcc1-usegcc ?= no | 20 | arm-libtcc1-usegcc ?= no |
| 23 | x86_64-libtcc1-usegcc ?= no | ||
| 24 | i386-libtcc1-usegcc ?= no | ||
| 25 | 21 | ||
| 26 | ifeq "$($(T)-libtcc1-usegcc)" "yes" | 22 | ifeq "$($(T)-libtcc1-usegcc)" "yes" |
| 27 | XCC = $(CC) | 23 | XCC = $(CC) |
| @@ -42,8 +38,6 @@ ifdef CONFIG_OSX · 14 unmodified lines | |||
| 42 | XFLAGS += -D_ANSI_SOURCE | 38 | XFLAGS += -D_ANSI_SOURCE |
| 43 | endif | 39 | endif |
| 44 | 40 | ||
| 45 | XFLAGS += -g | ||
| 46 | |||
| 47 | I386_O = libtcc1.o alloca86.o alloca86-bt.o | 41 | I386_O = libtcc1.o alloca86.o alloca86-bt.o |
| 48 | X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o | 42 | X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o |
| 49 | ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o | 43 | ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o |
| @@ -51,11 +45,11 @@ ARM64_O = lib-arm64.o · 1 unmodified line | |||
| 51 | RISCV64_O = lib-arm64.o | 45 | RISCV64_O = lib-arm64.o |
| 52 | WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o | 46 | WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o |
| 53 | 47 | ||
| 54 | OBJ-i386 = $(I386_O) $(DSO_O) | 48 | OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O) |
| 55 | OBJ-x86_64 = $(X86_64_O) va_list.o $(DSO_O) | 49 | OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) $(DSO_O) |
| 56 | OBJ-x86_64-osx = $(X86_64_O) va_list.o | 50 | OBJ-x86_64-osx = $(X86_64_O) va_list.o |
| 57 | OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O) | 51 | OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O) |
| 58 | OBJ-x86_64-win32 = $(X86_64_O) chkstk.o (WIN_O) | 52 | OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O) |
| 59 | OBJ-arm64 = $(ARM64_O) $(DSO_O) | 53 | OBJ-arm64 = $(ARM64_O) $(DSO_O) |
| 60 | OBJ-arm = $(ARM_O) $(DSO_O) | 54 | OBJ-arm = $(ARM_O) $(DSO_O) |
| 61 | OBJ-arm-fpa = $(ARM_O) $(DSO_O) | 55 | OBJ-arm-fpa = $(ARM_O) $(DSO_O) |
| @@ -66,27 +60,14 @@ OBJ-arm-eabihf = $(ARM_O) $(DSO_O) · 4 unmodified lines | |||
| 66 | OBJ-arm-wince = $(ARM_O) $(WIN_O) | 60 | OBJ-arm-wince = $(ARM_O) $(WIN_O) |
| 67 | OBJ-riscv64 = $(RISCV64_O) $(DSO_O) | 61 | OBJ-riscv64 = $(RISCV64_O) $(DSO_O) |
| 68 | 62 | ||
| 69 | OBJB-i386 = $(BCHECK_O) | 63 | OBJ-extra = $(filter bcheck.o,$(OBJ-$T)) |
| 70 | OBJB-x86_64 = $(BCHECK_O) | 64 | OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T))) |
| 71 | OBJB-x86_64-osx = dummy.o | 65 | |
| 72 | OBJB-i386-win32 = bcheck.o | 66 | ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra)) |
| 73 | OBJB-x86_64-win32 = bcheck.o | 67 | |
| 74 | OBJB-arm64 = dummy.o | 68 | all: $(ALL) |
| 75 | OBJB-arm = dummy.o | ||
| 76 | OBJB-arm-fpa = dummy.o | ||
| 77 | OBJB-arm-fpa-ld = dummy.o | ||
| 78 | OBJB-arm-vfp = dummy.o | ||
| 79 | OBJB-arm-eabi = dummy.o | ||
| 80 | OBJB-arm-eabihf = dummy.o | ||
| 81 | OBJB-arm-wince = dummy.o | ||
| 82 | OBJB-riscv64 = dummy.o | ||
| 83 | |||
| 84 | all: $(BIN) $(BINB) | ||
| 85 | |||
| 86 | $(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T)) | ||
| 87 | $(XAR) rcs $@ $^ | ||
| 88 | 69 | ||
| 89 | $(BINB) : $(patsubst %.o,$(X)%.o,$(OBJB-$T)) | 70 | $(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1) |
| 90 | $(XAR) rcs $@ $^ | 71 | $(XAR) rcs $@ $^ |
| 91 | 72 | ||
| 92 | $(X)%.o : %.c | 73 | $(X)%.o : %.c |
| @@ -95,8 +76,12 @@ $(X)%.o : %.c · 2 unmodified lines | |||
| 95 | $(X)%.o : %.S | 76 | $(X)%.o : %.S |
| 96 | $(XCC) -c $< -o $@ $(XFLAGS) | 77 | $(XCC) -c $< -o $@ $(XFLAGS) |
| 97 | 78 | ||
| 79 | $(TOP)/%.o : %.c | ||
| 80 | $(XCC) -c $< -o $@ $(XFLAGS) | ||
| 81 | |||
| 82 | $(TOP)/bcheck.o : XFLAGS += -g | ||
| 83 | |||
| 98 | $(X)crt1w.o : crt1.c | 84 | $(X)crt1w.o : crt1.c |
| 99 | $(X)wincrt1w.o : wincrt1.c | 85 | $(X)wincrt1w.o : wincrt1.c |
| 100 | |||
| 101 | clean : | 86 | clean : |
| 102 | rm -f *.a *.o $(BIN) $(BINB) | 87 | rm -f *.a *.o $(ALL) |
| @@ -5,44 +5,25 @@ · 4 unmodified lines | |||
| 5 | __bound_alloca: | 5 | __bound_alloca: |
| 6 | 6 | ||
| 7 | #ifdef _WIN32 | 7 | #ifdef _WIN32 |
| 8 | pop %rdx | 8 | inc %rcx # add one extra to separate regions |
| 9 | mov %rcx,%rax | 9 | jmp alloca |
| 10 | add $15,%rax | 10 | .globl __bound_alloca_nr |
| 11 | and $-16,%rax | 11 | __bound_alloca_nr: |
| 12 | jz p3 | 12 | dec %rcx |
| 13 | |||
| 14 | p1: | ||
| 15 | cmp $4096,%rax | ||
| 16 | jbe p2 | ||
| 17 | test %rax,-4096(%rsp) | ||
| 18 | sub $4096,%rsp | ||
| 19 | sub $4096,%rax | ||
| 20 | jmp p1 | ||
| 21 | p2: | ||
| 22 | |||
| 23 | sub %rax,%rsp | ||
| 24 | mov %rsp,%rax | ||
| 25 | |||
| 26 | push %rdx | ||
| 27 | push %rax | 13 | push %rax |
| 28 | mov %rcx,%rdx | 14 | mov %rcx,%rdx |
| 29 | mov %rax,%rcx | 15 | mov %rax,%rcx |
| 30 | sub $20,%rsp | 16 | sub $32,%rsp |
| 31 | call __bound_new_region | 17 | call __bound_new_region |
| 32 | add $20,%rsp | 18 | add $32,%rsp |
| 33 | pop %rax | 19 | pop %rax |
| 34 | pop %rdx | ||
| 35 | |||
| 36 | add $32,%rax | ||
| 37 | p3: | ||
| 38 | push %rdx | ||
| 39 | ret | 20 | ret |
| 40 | #else | 21 | #else |
| 41 | pop %rdx | 22 | pop %rdx |
| 42 | mov %rdi,%rax | 23 | mov %rdi,%rax |
| 43 | mov %rax,%rsi # size, a second parm to the __bound_new_region | 24 | mov %rax,%rsi # size, a second parm to the __bound_new_region |
| 44 | 25 | ||
| 45 | add $15,%rax | 26 | add $15 + 1,%rax # add one extra to separate regions |
| 46 | and $-16,%rax | 27 | and $-16,%rax |
| 47 | jz p3 | 28 | jz p3 |
| 48 | 29 | ||
| @@ -24,12 +24,8 @@ p1: · 23 unmodified lines | |||
| 24 | jmp p1 | 24 | jmp p1 |
| 25 | p2: | 25 | p2: |
| 26 | #endif | 26 | #endif |
| 27 | |||
| 28 | sub %rax,%rsp | 27 | sub %rax,%rsp |
| 29 | mov %rsp,%rax | 28 | mov %rsp,%rax |
| 30 | #ifdef _WIN32 | ||
| 31 | add $32,%rax | ||
| 32 | #endif | ||
| 33 | p3: | 29 | p3: |
| 34 | push %rdx | 30 | push %rdx |
| 35 | ret | 31 | ret |
| @@ -205,6 +205,9 @@ void __bound_checking (int no_check) · 204 unmodified lines | |||
| 205 | no_checking = no_check; | 205 | no_checking = no_check; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | #define no_FASTCALL | ||
| 209 | //#define no_checking 1 | ||
| 210 | |||
| 208 | /* print a bound error message */ | 211 | /* print a bound error message */ |
| 209 | static void bound_error(const char *fmt, ...) | 212 | static void bound_error(const char *fmt, ...) |
| 210 | { | 213 | { |
| @@ -221,8 +224,7 @@ static void bound_alloc_error(void) · 10 unmodified lines | |||
| 221 | 224 | ||
| 222 | /* return '(p + offset)' for pointer arithmetic (a pointer can reach | 225 | /* return '(p + offset)' for pointer arithmetic (a pointer can reach |
| 223 | the end of a region in this case */ | 226 | the end of a region in this case */ |
| 224 | void * FASTCALL __bound_ptr_add(void *p, size_t offset, | 227 | void * no_FASTCALL __bound_ptr_add(void *p, size_t offset) |
| 225 | size_t line, const char *filename) | ||
| 226 | { | 228 | { |
| 227 | size_t addr = (size_t)p; | 229 | size_t addr = (size_t)p; |
| 228 | 230 | ||
| @@ -230,8 +232,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 1 unmodified line | |||
| 230 | return p + offset; | 232 | return p + offset; |
| 231 | } | 233 | } |
| 232 | 234 | ||
| 233 | dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n", | 235 | dprintf(stderr, "%s %s : %p 0x%x\n", |
| 234 | __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); | 236 | __FILE__, __FUNCTION__, p, (unsigned)offset); |
| 235 | 237 | ||
| 236 | WAIT_SEM (); | 238 | WAIT_SEM (); |
| 237 | INCR_COUNT(bound_ptr_add_count); | 239 | INCR_COUNT(bound_ptr_add_count); |
| @@ -250,8 +252,10 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 12 unmodified lines | |||
| 250 | if (addr <= tree->size) { | 252 | if (addr <= tree->size) { |
| 251 | addr += offset; | 253 | addr += offset; |
| 252 | if (tree->is_invalid || addr > tree->size) { | 254 | if (tree->is_invalid || addr > tree->size) { |
| 253 | fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", | 255 | #if 0 |
| 254 | __FILE__, __FUNCTION__, filename, line, p + offset); | 256 | fprintf(stderr,"%s %s : %p is outside of the region\n", |
| 257 | __FILE__, __FUNCTION__, p + offset); | ||
| 258 | #endif | ||
| 255 | if (never_fatal == 0) { | 259 | if (never_fatal == 0) { |
| 256 | POST_SEM (); | 260 | POST_SEM (); |
| 257 | return INVALID_POINTER; /* return an invalid pointer */ | 261 | return INVALID_POINTER; /* return an invalid pointer */ |
| @@ -266,16 +270,15 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 8 unmodified lines | |||
| 266 | /* return '(p + offset)' for pointer indirection (the resulting must | 270 | /* return '(p + offset)' for pointer indirection (the resulting must |
| 267 | be strictly inside the region */ | 271 | be strictly inside the region */ |
| 268 | #define BOUND_PTR_INDIR(dsize) \ | 272 | #define BOUND_PTR_INDIR(dsize) \ |
| 269 | void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \ | 273 | void * no_FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ |
| 270 | size_t line, const char *filename) \ | ||
| 271 | { \ | 274 | { \ |
| 272 | size_t addr = (size_t)p; \ | 275 | size_t addr = (size_t)p; \ |
| 273 | \ | 276 | \ |
| 274 | if (no_checking) { \ | 277 | if (no_checking) { \ |
| 275 | return p + offset; \ | 278 | return p + offset; \ |
| 276 | } \ | 279 | } \ |
| 277 | dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n", \ | 280 | dprintf(stderr, "%s %s : %p 0x%x start\n", \ |
| 278 | __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); \ | 281 | __FILE__, __FUNCTION__, p, (unsigned)offset); \ |
| 279 | WAIT_SEM (); \ | 282 | WAIT_SEM (); \ |
| 280 | INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ | 283 | INCR_COUNT(bound_ptr_indir ## dsize ## _count); \ |
| 281 | if (tree) { \ | 284 | if (tree) { \ |
| @@ -293,8 +296,8 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \ · 11 unmodified lines | |||
| 293 | if (addr <= tree->size) { \ | 296 | if (addr <= tree->size) { \ |
| 294 | addr += offset + dsize; \ | 297 | addr += offset + dsize; \ |
| 295 | if (tree->is_invalid || addr > tree->size) { \ | 298 | if (tree->is_invalid || addr > tree->size) { \ |
| 296 | fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \ | 299 | fprintf(stderr,"%s %s : %p is outside of the region\n", \ |
| 297 | __FILE__, __FUNCTION__, filename, line, p + offset); \ | 300 | __FILE__, __FUNCTION__, p + offset); \ |
| 298 | if (never_fatal == 0) { \ | 301 | if (never_fatal == 0) { \ |
| 299 | POST_SEM (); \ | 302 | POST_SEM (); \ |
| 300 | return INVALID_POINTER; /* return an invalid pointer */ \ | 303 | return INVALID_POINTER; /* return an invalid pointer */ \ |
| @@ -907,7 +910,7 @@ static void __bound_check(const void *p, size_t size, const char *function) · 606 unmodified lines | |||
| 907 | return; | 910 | return; |
| 908 | if (size == 0) | 911 | if (size == 0) |
| 909 | return; | 912 | return; |
| 910 | p = __bound_ptr_add((void *)p, size, 0, function); | 913 | p = __bound_ptr_add((void *)p, size); |
| 911 | if (p == INVALID_POINTER) | 914 | if (p == INVALID_POINTER) |
| 912 | bound_error("invalid pointer"); | 915 | bound_error("invalid pointer"); |
| 913 | } | 916 | } |
| @@ -959,7 +962,7 @@ int __bound_strlen(const char *s) · 45 unmodified lines | |||
| 959 | INCR_COUNT(bound_strlen_count); | 962 | INCR_COUNT(bound_strlen_count); |
| 960 | while (*p++); | 963 | while (*p++); |
| 961 | len = (p - s) - 1; | 964 | len = (p - s) - 1; |
| 962 | p = __bound_ptr_indir1((char *)s, len, 0, "strlen"); | 965 | p = __bound_ptr_indir1((char *)s, len); |
| 963 | if (p == INVALID_POINTER) | 966 | if (p == INVALID_POINTER) |
| 964 | bound_error("bad pointer in strlen()"); | 967 | bound_error("bad pointer in strlen()"); |
| 965 | return len; | 968 | return len; |
| @@ -1 +0,0 @@ | |||
| 1 | static char dummy; | ||