History

Add new bounds checking functions.

The following functions are now also bounds checked: memcmp, strncpy, strcmp, strncmp, strcat, strchr, strdup. Add statistics code for bounds checking functions. The statistics can be printed by settings environment variable "TCC_BOUNDS_PRINT_STATISTIC". Enabled more tests in test/Makefile.

herman ten brugge committed 6 years ago

Commit 39c0ff31 parent 35512be6 files · +235 −29Browse files

Unified · Split

6 files
  1. lib/Makefile +1 −1
  2. lib/bcheck.c +204 −14
  3. tcc-doc.texi +5 −3
  4. tccgen.c +7 −0
  5. tcctok.h +7 −0
  6. tests/Makefile +11 −11
lib/Makefile+1−1
@@ -42,7 +42,7 @@ ifdef CONFIG_OSX · 41 unmodified lines
42 XFLAGS += -D_ANSI_SOURCE42 XFLAGS += -D_ANSI_SOURCE
43endif43endif
44 44
45XFLAGS += -g -Wno-deprecated-declarations45XFLAGS += -g
46 46
47I386_O = libtcc1.o alloca86.o alloca86-bt.o47I386_O = libtcc1.o alloca86.o alloca86-bt.o
48X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o48X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
lib/bcheck.c+204−14
@@ -35,6 +35,7 @@ · 34 unmodified lines
35#endif35#endif
36 36
37#define BOUND_DEBUG37#define BOUND_DEBUG
38#define BOUND_STATISTIC
38 39
39#ifdef BOUND_DEBUG40#ifdef BOUND_DEBUG
40 #define dprintf(a...) if (print_calls) fprintf(a)41 #define dprintf(a...) if (print_calls) fprintf(a)
@@ -50,8 +51,7 @@ · 9 unmodified lines
50 || defined(__DragonFly__) \51 || defined(__DragonFly__) \
51 || defined(__OpenBSD__) \52 || defined(__OpenBSD__) \
52 || defined(__NetBSD__) \53 || defined(__NetBSD__) \
53 || defined(__dietlibc__) \54 || defined(__dietlibc__)
54 || defined(_WIN32)
55#undef HAVE_MEMALIGN55#undef HAVE_MEMALIGN
56#define INIT_SEM()56#define INIT_SEM()
57#define EXIT_SEM()57#define EXIT_SEM()
@@ -59,6 +59,16 @@ · 1 unmodified line
59#define POST_SEM()59#define POST_SEM()
60#define HAS_ENVIRON 060#define HAS_ENVIRON 0
61#define MALLOC_REDIR (0)61#define MALLOC_REDIR (0)
62#elif defined(_WIN32)
63#include <windows.h>
64#undef HAVE_MEMALIGN
65static CRITICAL_SECTION bounds_sem;
66#define INIT_SEM() InitializeCriticalSection(&bounds_sem)
67#define EXIT_SEM() DeleteCriticalSection(&bounds_sem)
68#define WAIT_SEM() EnterCriticalSection(&bounds_sem)
69#define POST_SEM() LeaveCriticalSection(&bounds_sem)
70#define HAS_ENVIRON 0
71#define MALLOC_REDIR (0)
62#else72#else
63#include <sys/mman.h>73#include <sys/mman.h>
64#include <errno.h>74#include <errno.h>
@@ -86,6 +96,7 @@ static unsigned char initial_pool[256]; · 21 unmodified lines
86#define TCC_TYPE_CALLOC (2)96#define TCC_TYPE_CALLOC (2)
87#define TCC_TYPE_REALLOC (3)97#define TCC_TYPE_REALLOC (3)
88#define TCC_TYPE_MEMALIGN (4)98#define TCC_TYPE_MEMALIGN (4)
99#define TCC_TYPE_STRDUP (5)
89 100
90/* this pointer is generated when bound check is incorrect */101/* this pointer is generated when bound check is incorrect */
91#define INVALID_POINTER ((void *)(-2))102#define INVALID_POINTER ((void *)(-2))
@@ -149,9 +160,45 @@ static alloca_list_type *alloca_list = NULL; · 57 unmodified lines
149static int inited = 0;160static int inited = 0;
150static int print_calls = 0;161static int print_calls = 0;
151static int print_heap = 0;162static int print_heap = 0;
163static int print_statistic = 0;
152static int never_fatal = 0;164static int never_fatal = 0;
153static int no_checking = 0;165static int no_checking = 0;
154 166
167#ifdef BOUND_STATISTIC
168static unsigned long bound_ptr_add_count;
169static unsigned long bound_ptr_indir1_count;
170static unsigned long bound_ptr_indir2_count;
171static unsigned long bound_ptr_indir4_count;
172static unsigned long bound_ptr_indir8_count;
173static unsigned long bound_ptr_indir12_count;
174static unsigned long bound_ptr_indir16_count;
175static unsigned long bound_local_new_count;
176static unsigned long bound_local_delete_count;
177static unsigned long bound_malloc_count;
178static unsigned long bound_calloc_count;
179static unsigned long bound_realloc_count;
180static unsigned long bound_free_count;
181static unsigned long bound_memalign_count;
182static unsigned long bound_mmap_count;
183static unsigned long bound_munmap_count;
184static unsigned long bound_alloca_count;
185static unsigned long bound_mempcy_count;
186static unsigned long bound_memcmp_count;
187static unsigned long bound_memmove_count;
188static unsigned long bound_memset_count;
189static unsigned long bound_strlen_count;
190static unsigned long bound_strcpy_count;
191static unsigned long bound_strncpy_count;
192static unsigned long bound_strcmp_count;
193static unsigned long bound_strncmp_count;
194static unsigned long bound_strcat_count;
195static unsigned long bound_strchr_count;
196static unsigned long bound_strdup_count;
197#define INCR_COUNT(x) x++
198#else
199#define INCR_COUNT(x)
200#endif
201
155/* enable/disable checking. This can be used for signal handlers. */202/* enable/disable checking. This can be used for signal handlers. */
156void __bound_checking (int no_check)203void __bound_checking (int no_check)
157{204{
@@ -186,6 +233,7 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset) · 28 unmodified lines
186 __FILE__, __FUNCTION__, p, (unsigned)offset);233 __FILE__, __FUNCTION__, p, (unsigned)offset);
187 234
188 WAIT_SEM ();235 WAIT_SEM ();
236 INCR_COUNT(bound_ptr_add_count);
189 if (tree) {237 if (tree) {
190 tree = splay (addr, tree);238 tree = splay (addr, tree);
191 addr -= tree->start;239 addr -= tree->start;
@@ -223,6 +271,7 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ · 31 unmodified lines
223 dprintf(stderr, "%s %s: %p 0x%x start\n", \271 dprintf(stderr, "%s %s: %p 0x%x start\n", \
224 __FILE__, __FUNCTION__, p, (unsigned)offset); \272 __FILE__, __FUNCTION__, p, (unsigned)offset); \
225 WAIT_SEM (); \273 WAIT_SEM (); \
274 INCR_COUNT(bound_ptr_indir ## dsize ## _count); \
226 if (tree) { \275 if (tree) { \
227 tree = splay (addr, tree); \276 tree = splay (addr, tree); \
228 addr -= tree->start; \277 addr -= tree->start; \
@@ -284,6 +333,7 @@ void FASTCALL __bound_local_new(void *p1) · 55 unmodified lines
284 addr = p[0];333 addr = p[0];
285 if (addr == 0)334 if (addr == 0)
286 break;335 break;
336 INCR_COUNT(bound_local_new_count);
287 if (addr == 1) {337 if (addr == 1) {
288 dprintf(stderr, "%s, %s() alloca/vla used\n",338 dprintf(stderr, "%s, %s() alloca/vla used\n",
289 __FILE__, __FUNCTION__);339 __FILE__, __FUNCTION__);
@@ -315,6 +365,7 @@ void FASTCALL __bound_local_delete(void *p1) · 25 unmodified lines
315 addr = p[0];365 addr = p[0];
316 if (addr == 0)366 if (addr == 0)
317 break;367 break;
368 INCR_COUNT(bound_local_delete_count);
318 if (addr == 1) {369 if (addr == 1) {
319 while (alloca_list && alloca_list->fp == fp) {370 while (alloca_list && alloca_list->fp == fp) {
320 alloca_list_type *next = alloca_list->next;371 alloca_list_type *next = alloca_list->next;
@@ -350,6 +401,7 @@ void __bound_init(void) · 29 unmodified lines
350 401
351 print_calls = getenv ("TCC_BOUNDS_PRINT_CALLS") != NULL;402 print_calls = getenv ("TCC_BOUNDS_PRINT_CALLS") != NULL;
352 print_heap = getenv ("TCC_BOUNDS_PRINT_HEAP") != NULL;403 print_heap = getenv ("TCC_BOUNDS_PRINT_HEAP") != NULL;
404 print_statistic = getenv ("TCC_BOUNDS_PRINT_STATISTIC") != NULL;
353 never_fatal = getenv ("TCC_BOUNDS_NEVER_FATAL") != NULL;405 never_fatal = getenv ("TCC_BOUNDS_NEVER_FATAL") != NULL;
354 406
355 dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);407 dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
@@ -444,7 +496,7 @@ void __attribute__((destructor)) __bound_exit(void) · 88 unmodified lines
444{496{
445 int i;497 int i;
446 static const char * const alloc_type[] = {498 static const char * const alloc_type[] = {
447 "", "malloc", "calloc", "realloc", "memalign"499 "", "malloc", "calloc", "realloc", "memalign", "strdup"
448 };500 };
449 501
450 dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);502 dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
@@ -488,6 +540,39 @@ void __attribute__((destructor)) __bound_exit(void) · 37 unmodified lines
488 }540 }
489 EXIT_SEM ();541 EXIT_SEM ();
490 inited = 0;542 inited = 0;
543#ifdef BOUND_STATISTIC
544 if (print_statistic) {
545 fprintf (stderr, "bound_ptr_add_count %llu\n", bound_ptr_add_count);
546 fprintf (stderr, "bound_ptr_indir1_count %llu\n", bound_ptr_indir1_count);
547 fprintf (stderr, "bound_ptr_indir2_count %llu\n", bound_ptr_indir2_count);
548 fprintf (stderr, "bound_ptr_indir4_count %llu\n", bound_ptr_indir4_count);
549 fprintf (stderr, "bound_ptr_indir8_count %llu\n", bound_ptr_indir8_count);
550 fprintf (stderr, "bound_ptr_indir12_count %llu\n", bound_ptr_indir12_count);
551 fprintf (stderr, "bound_ptr_indir16_count %llu\n", bound_ptr_indir16_count);
552 fprintf (stderr, "bound_local_new_count %llu\n", bound_local_new_count);
553 fprintf (stderr, "bound_local_delete_count %llu\n", bound_local_delete_count);
554 fprintf (stderr, "bound_malloc_count %llu\n", bound_malloc_count);
555 fprintf (stderr, "bound_calloc_count %llu\n", bound_calloc_count);
556 fprintf (stderr, "bound_realloc_count %llu\n", bound_realloc_count);
557 fprintf (stderr, "bound_free_count %llu\n", bound_free_count);
558 fprintf (stderr, "bound_memalign_count %llu\n", bound_memalign_count);
559 fprintf (stderr, "bound_mmap_count %llu\n", bound_mmap_count);
560 fprintf (stderr, "bound_munmap_count %llu\n", bound_munmap_count);
561 fprintf (stderr, "bound_alloca_count %llu\n", bound_alloca_count);
562 fprintf (stderr, "bound_mempcy_count %llu\n", bound_mempcy_count);
563 fprintf (stderr, "bound_memcmp_count %llu\n", bound_memcmp_count);
564 fprintf (stderr, "bound_memmove_count %llu\n", bound_memmove_count);
565 fprintf (stderr, "bound_memset_count %llu\n", bound_memset_count);
566 fprintf (stderr, "bound_strlen_count %llu\n", bound_strlen_count);
567 fprintf (stderr, "bound_strcpy_count %llu\n", bound_strcpy_count);
568 fprintf (stderr, "bound_strncpy_count %llu\n", bound_strncpy_count);
569 fprintf (stderr, "bound_strcmp_count %llu\n", bound_strcmp_count);
570 fprintf (stderr, "bound_strncmp_count %llu\n", bound_strncmp_count);
571 fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_count);
572 fprintf (stderr, "bound_strchr_count %llu\n", bound_strchr_count);
573 fprintf (stderr, "bound_strdup_count %llu\n", bound_strdup_count);
574 }
575#endif
491 }576 }
492}577}
493 578
@@ -516,6 +601,7 @@ void *__bound_malloc(size_t size, const void *caller) · 22 unmodified lines
516 separated by at least one byte. With the glibc malloc, it may601 separated by at least one byte. With the glibc malloc, it may
517 be in fact not necessary */602 be in fact not necessary */
518 WAIT_SEM ();603 WAIT_SEM ();
604 INCR_COUNT(bound_malloc_count);
519#if MALLOC_REDIR605#if MALLOC_REDIR
520 ptr = malloc_redir (size);606 ptr = malloc_redir (size);
521#else607#else
@@ -544,6 +630,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) · 22 unmodified lines
544 void *ptr;630 void *ptr;
545 631
546 WAIT_SEM ();632 WAIT_SEM ();
633 INCR_COUNT(bound_memalign_count);
547 634
548#ifndef HAVE_MEMALIGN635#ifndef HAVE_MEMALIGN
549 if (align > 4) {636 if (align > 4) {
@@ -599,6 +686,7 @@ void __bound_free(void *ptr, const void *caller) · 49 unmodified lines
599 dprintf(stderr, "%s, %s (%p)\n", __FILE__, __FUNCTION__, ptr);686 dprintf(stderr, "%s, %s (%p)\n", __FILE__, __FUNCTION__, ptr);
600 687
601 WAIT_SEM ();688 WAIT_SEM ();
689 INCR_COUNT(bound_free_count);
602 tree = splay (addr, tree);690 tree = splay (addr, tree);
603 if (tree->start == addr) {691 if (tree->start == addr) {
604 if (tree->is_invalid) {692 if (tree->is_invalid) {
@@ -645,6 +733,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller) · 40 unmodified lines
645 ptr = realloc (ptr, size);733 ptr = realloc (ptr, size);
646#endif734#endif
647 WAIT_SEM ();735 WAIT_SEM ();
736 INCR_COUNT(bound_realloc_count);
648 if (ptr) {737 if (ptr) {
649 tree = splay_insert ((size_t) ptr, size, tree);738 tree = splay_insert ((size_t) ptr, size, tree);
650 if (tree->start == (size_t) ptr) {739 if (tree->start == (size_t) ptr) {
@@ -701,6 +790,7 @@ void *__bound_calloc(size_t nmemb, size_t size) · 50 unmodified lines
701 if (ptr) {790 if (ptr) {
702 memset (ptr, 0, size);791 memset (ptr, 0, size);
703 WAIT_SEM ();792 WAIT_SEM ();
793 INCR_COUNT(bound_calloc_count);
704 tree = splay_insert ((size_t) ptr, size, tree);794 tree = splay_insert ((size_t) ptr, size, tree);
705 if (tree->start == (size_t) ptr) {795 if (tree->start == (size_t) ptr) {
706 tree->type = TCC_TYPE_CALLOC;796 tree->type = TCC_TYPE_CALLOC;
@@ -721,6 +811,7 @@ void *__bound_mmap (void *start, size_t size, int prot, · 14 unmodified lines
721 result = mmap (start, size, prot, flags, fd, offset);811 result = mmap (start, size, prot, flags, fd, offset);
722 if (result) {812 if (result) {
723 WAIT_SEM ();813 WAIT_SEM ();
814 INCR_COUNT(bound_mmap_count);
724 tree = splay_insert((size_t)result, size, tree);815 tree = splay_insert((size_t)result, size, tree);
725 POST_SEM ();816 POST_SEM ();
726 }817 }
@@ -734,6 +825,7 @@ int __bound_munmap (void *start, size_t size) · 7 unmodified lines
734 dprintf(stderr, "%s, %s (%p, 0x%x)\n",825 dprintf(stderr, "%s, %s (%p, 0x%x)\n",
735 __FILE__, __FUNCTION__, start, (unsigned)size);826 __FILE__, __FUNCTION__, start, (unsigned)size);
736 WAIT_SEM ();827 WAIT_SEM ();
828 INCR_COUNT(bound_munmap_count);
737 tree = splay_delete ((size_t) start, tree);829 tree = splay_delete ((size_t) start, tree);
738 POST_SEM ();830 POST_SEM ();
739 result = munmap (start, size);831 result = munmap (start, size);
@@ -751,6 +843,7 @@ void __bound_new_region(void *p, size_t size) · 11 unmodified lines
751 dprintf(stderr, "%s, %s (%p, 0x%x)\n",843 dprintf(stderr, "%s, %s (%p, 0x%x)\n",
752 __FILE__, __FUNCTION__, p, (unsigned)size);844 __FILE__, __FUNCTION__, p, (unsigned)size);
753 WAIT_SEM ();845 WAIT_SEM ();
846 INCR_COUNT(bound_alloca_count);
754 GET_CALLER_FP (fp);847 GET_CALLER_FP (fp);
755 last = NULL;848 last = NULL;
756 cur = alloca_list;849 cur = alloca_list;
@@ -813,6 +906,7 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 56 unmodified lines
813{906{
814 void* p;907 void* p;
815 908
909 INCR_COUNT(bound_mempcy_count);
816 __bound_check(dst, size);910 __bound_check(dst, size);
817 __bound_check(src, size);911 __bound_check(src, size);
818 /* check also region overlap */912 /* check also region overlap */
@@ -824,8 +918,17 @@ void *__bound_memcpy(void *dst, const void *src, size_t size) · 5 unmodified lines
824 return p;918 return p;
825}919}
826 920
921int __bound_memcmp(const void *s1, const void *s2, size_t size)
922{
923 INCR_COUNT(bound_memcmp_count);
924 __bound_check(s1, size);
925 __bound_check(s2, size);
926 return memcmp(s1, s2, size);
927}
928
827void *__bound_memmove(void *dst, const void *src, size_t size)929void *__bound_memmove(void *dst, const void *src, size_t size)
828{930{
931 INCR_COUNT(bound_memmove_count);
829 __bound_check(dst, size);932 __bound_check(dst, size);
830 __bound_check(src, size);933 __bound_check(src, size);
831 return memmove(dst, src, size);934 return memmove(dst, src, size);
@@ -833,25 +936,22 @@ void *__bound_memmove(void *dst, const void *src, size_t size) · 1 unmodified line
833 936
834void *__bound_memset(void *dst, int c, size_t size)937void *__bound_memset(void *dst, int c, size_t size)
835{938{
939 INCR_COUNT(bound_memset_count);
836 __bound_check(dst, size);940 __bound_check(dst, size);
837 return memset(dst, c, size);941 return memset(dst, c, size);
838}942}
839 943
840/* XXX: could be optimized */
841int __bound_strlen(const char *s)944int __bound_strlen(const char *s)
842{945{
843 const char *p;946 const char *p = s;
844 size_t len;947 size_t len;
845 948
846 len = 0;949 INCR_COUNT(bound_strlen_count);
847 for(;;) {950 while (*p++);
848 p = __bound_ptr_indir1((char *)s, len);951 len = (p - s) - 1;
849 if (p == INVALID_POINTER)952 p = __bound_ptr_indir1((char *)s, len);
850 bound_error("bad pointer in strlen()");953 if (p == INVALID_POINTER)
851 if (*p == '\0')954 bound_error("bad pointer in strlen()");
852 break;
853 len++;
854 }
855 return len;955 return len;
856}956}
857 957
@@ -860,11 +960,101 @@ char *__bound_strcpy(char *dst, const char *src) · 2 unmodified lines
860 size_t len;960 size_t len;
861 void *p;961 void *p;
862 962
963 INCR_COUNT(bound_strcpy_count);
863 len = __bound_strlen(src);964 len = __bound_strlen(src);
864 p = __bound_memcpy(dst, src, len + 1);965 p = __bound_memcpy(dst, src, len + 1);
865 return p;966 return p;
866}967}
867 968
969char *__bound_strncpy(char *dst, const char *src, size_t n)
970{
971 size_t len;
972 void *p;
973
974 INCR_COUNT(bound_strncpy_count);
975 __bound_check(dst, n);
976 __bound_check(src, n);
977 return strncpy (dst, src, n);
978}
979
980int __bound_strcmp(const char *s1, const char *s2)
981{
982 const unsigned char *u1 = (const unsigned char *) s1;
983 const unsigned char *u2 = (const unsigned char *) s2;
984
985 INCR_COUNT(bound_strcmp_count);
986 while (*u1 && *u1 == *u2) {
987 u1++;
988 u2++;
989 }
990 __bound_check(s1, ((const char *)u1 - s1) + 1);
991 __bound_check(s2, ((const char *)u2 - s2) + 1);
992 return (*u1 - *u2);
993}
994
995int __bound_strncmp(const char *s1, const char *s2, size_t n)
996{
997 INCR_COUNT(bound_strncmp_count);
998 __bound_check(s1, n);
999 __bound_check(s2, n);
1000 return strncmp(s1, s2, n);
1001}
1002
1003char *__bound_strcat(char *dest, const char *src)
1004{
1005 char *r = dest;
1006 const char *s = src;
1007
1008 INCR_COUNT(bound_strcat_count);
1009 while (*dest++);
1010 dest--;
1011 while ((*dest++ = *src++) != 0);
1012 __bound_check(r, dest - r);
1013 __bound_check(s, src - s);
1014 return r;
1015}
1016
1017char *__bound_strchr(const char *string, int ch)
1018{
1019 const unsigned char *s = (const unsigned char *) string;
1020 unsigned char c = ch;
1021
1022 INCR_COUNT(bound_strchr_count);
1023 while (*s) {
1024 if (*s == c) {
1025 break;
1026 }
1027 s++;
1028 }
1029 __bound_check(string, ((const char *)s - string) + 1);
1030 return *s == c ? (char *) s : NULL;
1031}
1032
1033char *__bound_strdup(const char *s)
1034{
1035 const char *p = s;
1036 char *new;
1037
1038 INCR_COUNT(bound_strdup_count);
1039 while (*p++);
1040 __bound_check(s, p - s);
1041#if MALLOC_REDIR
1042 new = malloc_redir (p - s);
1043#else
1044 new = malloc (p - s);
1045#endif
1046 if (new) {
1047 WAIT_SEM ();
1048 tree = splay_insert((size_t)new, p - s, tree);
1049 if (tree->start == (size_t) new) {
1050 tree->type = TCC_TYPE_STRDUP;
1051 }
1052 memcpy (new, s, p - s);
1053 POST_SEM ();
1054 }
1055 return new;
1056}
1057
868/*1058/*
869 An implementation of top-down splaying with sizes1059 An implementation of top-down splaying with sizes
870 D. Sleator <sleator@cs.cmu.edu>, January 1994.1060 D. Sleator <sleator@cs.cmu.edu>, January 1994.
tcc-doc.texi+5−3
@@ -356,12 +356,14 @@ memory allocations and array/pointer bounds. @option{-g} is implied. Note · 355 unmodified lines
356that the generated code is slower and bigger in this case.356that the generated code is slower and bigger in this case.
357The bound checking code is not included in shared libaries. The main executable should always be compiled with the @option{-b}.357The bound checking code is not included in shared libaries. The main executable should always be compiled with the @option{-b}.
358 358
359There are three environment variables that can be used:359There are four environment variables that can be used:
360@table @option360@table @option
361@item TCC_BOUNDS_PRINT_CALLS361@item TCC_BOUNDS_PRINT_CALLS
362Print bound checking calls. Can be used for debugging.362Print bound checking calls. Can be used for debugging.
363@item TCC_BOUNDS_PRINT_HEAP363@item TCC_BOUNDS_PRINT_HEAP
364Print heap objects that are not freed at exit of program.364Print heap objects that are not freed at exit of program.
365@item TCC_BOUNDS_PRINT_STATISTIC
366Print statistic information at exit of program.
365@item TCC_BOUNDS_NEVER_FATAL367@item TCC_BOUNDS_NEVER_FATAL
366Try to continue in case of a bound checking error.368Try to continue in case of a bound checking error.
367@end table369@end table
@@ -915,7 +917,7 @@ Here are some examples of caught errors: · 547 unmodified lines
915 int *tab;917 int *tab;
916 tab = malloc(20 * sizeof(int));918 tab = malloc(20 * sizeof(int));
917 for(i=0;i<21;i++) @{919 for(i=0;i<21;i++) @{
918 sum += tab4[i];920 sum += tab[i];
919 @}921 @}
920 free(tab);922 free(tab);
921@}923@}
@@ -928,7 +930,7 @@ Here are some examples of caught errors: · 6 unmodified lines
928 tab = malloc(20 * sizeof(int));930 tab = malloc(20 * sizeof(int));
929 free(tab);931 free(tab);
930 for(i=0;i<20;i++) @{932 for(i=0;i<20;i++) @{
931 sum += tab4[i];933 sum += tab[i];
932 @}934 @}
933@}935@}
934@end example936@end example
tccgen.c+7−0
@@ -432,8 +432,15 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 431 unmodified lines
432 case TOK_memcpy:432 case TOK_memcpy:
433 case TOK_memmove:433 case TOK_memmove:
434 case TOK_memset:434 case TOK_memset:
435 case TOK_memcmp:
435 case TOK_strlen:436 case TOK_strlen:
436 case TOK_strcpy:437 case TOK_strcpy:
438 case TOK_strncpy:
439 case TOK_strcmp:
440 case TOK_strncmp:
441 case TOK_strcat:
442 case TOK_strchr:
443 case TOK_strdup:
437 case TOK_alloca:444 case TOK_alloca:
438 case TOK_mmap:445 case TOK_mmap:
439 case TOK_munmap:446 case TOK_munmap:
tcctok.h+7−0
@@ -314,8 +314,15 @@ · 313 unmodified lines
314# endif314# endif
315 DEF(TOK_mmap, "mmap")315 DEF(TOK_mmap, "mmap")
316 DEF(TOK_munmap, "munmap")316 DEF(TOK_munmap, "munmap")
317 DEF(TOK_memcmp, "memcmp")
317 DEF(TOK_strlen, "strlen")318 DEF(TOK_strlen, "strlen")
318 DEF(TOK_strcpy, "strcpy")319 DEF(TOK_strcpy, "strcpy")
320 DEF(TOK_strncpy, "strncpy")
321 DEF(TOK_strcmp, "strcmp")
322 DEF(TOK_strncmp, "strncmp")
323 DEF(TOK_strcat, "strcat")
324 DEF(TOK_strchr, "strchr")
325 DEF(TOK_strdup, "strdup")
319#endif326#endif
320 327
321/* Tiny Assembler */328/* Tiny Assembler */
tests/Makefile+11−11
@@ -23,13 +23,12 @@ TESTS = \ · 22 unmodified lines
23 tests2-dir \23 tests2-dir \
24 pp-dir24 pp-dir
25 25
26BTESTS = test1b test3b btest26BTESTS = test1b test3b btest test4
27 27
28# test4 -- problem with -static28# test4_static -- Not all relocation types are implemented yet.
29# asmtest / asmtest2 -- minor differences with gcc29# asmtest / asmtest2 -- minor differences with gcc
30# btest -- works on i386 (including win32)
31 30
32# bounds-checking is supported only on i38631# bounds-checking is supported on i386 and x86_64 on linux and windows
33ifeq ($(ARCH),i386)32ifeq ($(ARCH),i386)
34 TESTS += $(BTESTS)33 TESTS += $(BTESTS)
35endif34endif
@@ -116,7 +115,7 @@ test3 test3b: tcctest.c test.ref · 80 unmodified lines
116 $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3115 $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
117 @diff -u test.ref test.out3 && echo "Auto Test3 OK"116 @diff -u test.ref test.out3 && echo "Auto Test3 OK"
118 117
119test%b : TCCFLAGS += -b118test%b : TCCFLAGS += -b -ba
120 119
121# binary output test120# binary output test
122test4: tcctest.c test.ref121test4: tcctest.c test.ref
@@ -131,10 +130,12 @@ test4: tcctest.c test.ref · 8 unmodified lines
131 ./tcctest1 > test1.out130 ./tcctest1 > test1.out
132 @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi131 @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
133# dynamic output + bound check132# dynamic output + bound check
134 $(TCC) -b -o tcctest4 $<133 $(TCC) -b -ba -o tcctest4 $<
135 ./tcctest4 > test4.out134 ./tcctest4 > test4.out
136 @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi135 @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
137# static output136
137test4_static: tcctest.c test.ref
138# static output.
138 $(TCC) -static -o tcctest2 $<139 $(TCC) -static -o tcctest2 $<
139 ./tcctest2 > test2.out140 ./tcctest2 > test2.out
140 @if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi141 @if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
@@ -162,8 +163,7 @@ memtest: · 21 unmodified lines
162 163
163 164
164# memory and bound check auto test165# memory and bound check auto test
165# 3 is profiling test166BOUNDS_OK = 1 3 4 8 10 14 16
166BOUNDS_OK = 1 4 8 10 14 16
167BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17167BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17
168 168
169btest: boundtest.c169btest: boundtest.c
@@ -171,7 +171,7 @@ btest: boundtest.c · 1 unmodified line
171 @ulimit -c 0; \171 @ulimit -c 0; \
172 for i in $(BOUNDS_OK); do \172 for i in $(BOUNDS_OK); do \
173 echo ; echo --- boundtest $$i ---; \173 echo ; echo --- boundtest $$i ---; \
174 if $(TCC) -b -run $< $$i ; then \174 if $(TCC) -b -ba -run $< $$i ; then \
175 echo succeeded as expected; \175 echo succeeded as expected; \
176 else\176 else\
177 echo Failed positive test $$i ; exit 1 ; \177 echo Failed positive test $$i ; exit 1 ; \
@@ -179,7 +179,7 @@ btest: boundtest.c · 1 unmodified line
179 done ;\179 done ;\
180 for i in $(BOUNDS_FAIL); do \180 for i in $(BOUNDS_FAIL); do \
181 echo ; echo --- boundtest $$i ---; \181 echo ; echo --- boundtest $$i ---; \
182 if $(TCC) -b -run $< $$i ; then \182 if $(TCC) -b -ba -run $< $$i ; then \
183 echo Failed negative test $$i ; exit 1 ;\183 echo Failed negative test $$i ; exit 1 ;\
184 else\184 else\
185 echo failed as expected; \185 echo failed as expected; \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t