Add linenumber filename support for bounds checking.
This commit is contained in:
		
							parent
							
								
									56e70bfa31
								
							
						
					
					
						commit
						87639aae7c
					
				
					 3 changed files with 154 additions and 124 deletions
				
			
		
							
								
								
									
										43
									
								
								i386-gen.c
									
										
									
									
									
								
							
							
						
						
									
										43
									
								
								i386-gen.c
									
										
									
									
									
								
							| 
						 | 
					@ -1130,29 +1130,36 @@ ST_FUNC void gen_bounded_ptr_add(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* save all temporary registers */
 | 
					    /* save all temporary registers */
 | 
				
			||||||
    save_regs(0);
 | 
					    save_regs(0);
 | 
				
			||||||
    /* trick to get line/file_name in code */
 | 
					 | 
				
			||||||
    o(0xb8);
 | 
					 | 
				
			||||||
    gen_le32 (file->line_num);
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        int i;
 | 
					 | 
				
			||||||
        int len;
 | 
					 | 
				
			||||||
        char *cp = file->filename;
 | 
					 | 
				
			||||||
        while (*cp) cp++;
 | 
					 | 
				
			||||||
        while (cp != file->filename && cp[-1] != '/') cp--;
 | 
					 | 
				
			||||||
        len = strlen (cp);
 | 
					 | 
				
			||||||
        while (len > 0) {
 | 
					 | 
				
			||||||
            memcpy (&i, cp, 4);
 | 
					 | 
				
			||||||
            o(0xb8);
 | 
					 | 
				
			||||||
            gen_le32 (i);
 | 
					 | 
				
			||||||
            cp += 4;
 | 
					 | 
				
			||||||
            len -= 4;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /* prepare fast i386 function call (args in eax and edx) */
 | 
					    /* prepare fast i386 function call (args in eax and edx) */
 | 
				
			||||||
    gv2(RC_EAX, RC_EDX);
 | 
					    gv2(RC_EAX, RC_EDX);
 | 
				
			||||||
    vtop -= 2;
 | 
					    vtop -= 2;
 | 
				
			||||||
 | 
					    /* add line, filename */
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        static addr_t offset;
 | 
				
			||||||
 | 
					        static char last_filename[1024];
 | 
				
			||||||
 | 
					        Sym *sym_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (strcmp (last_filename, file->filename) != 0) {
 | 
				
			||||||
 | 
					            void *ptr;
 | 
				
			||||||
 | 
					            int len = strlen (file->filename) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            offset = data_section->data_offset;
 | 
				
			||||||
 | 
					            ptr = section_ptr_add(data_section, len);
 | 
				
			||||||
 | 
					            memcpy (ptr, file->filename, len);
 | 
				
			||||||
 | 
					            memcpy (last_filename, file->filename, len);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        o(0xb9);   /* mov $xx,%ecx */
 | 
				
			||||||
 | 
					        gen_le32 (0);
 | 
				
			||||||
 | 
					        sym_data = get_sym_ref(&char_pointer_type, data_section,
 | 
				
			||||||
 | 
					                               offset, data_section->data_offset);
 | 
				
			||||||
 | 
					        greloca(cur_text_section, sym_data, ind - 4, R_386_32, 0);
 | 
				
			||||||
 | 
					        o(0x51);   /* push %ecx */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    o(0xb9);       /* mov $xx,%ecx */
 | 
				
			||||||
 | 
					    gen_le32 (file->line_num);
 | 
				
			||||||
    /* do a fast function call */
 | 
					    /* do a fast function call */
 | 
				
			||||||
    gen_static_call(TOK___bound_ptr_add);
 | 
					    gen_static_call(TOK___bound_ptr_add);
 | 
				
			||||||
 | 
					    o(0x04c483);   /* add $4,%esp */
 | 
				
			||||||
    /* returned pointer is in eax */
 | 
					    /* returned pointer is in eax */
 | 
				
			||||||
    vtop++;
 | 
					    vtop++;
 | 
				
			||||||
    vtop->r = TREG_EAX | VT_BOUNDED;
 | 
					    vtop->r = TREG_EAX | VT_BOUNDED;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										82
									
								
								lib/bcheck.c
									
										
									
									
									
								
							
							
						
						
									
										82
									
								
								lib/bcheck.c
									
										
									
									
									
								
							| 
						 | 
					@ -221,7 +221,8 @@ static void bound_alloc_error(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* return '(p + offset)' for pointer arithmetic (a pointer can reach
 | 
					/* return '(p + offset)' for pointer arithmetic (a pointer can reach
 | 
				
			||||||
   the end of a region in this case */
 | 
					   the end of a region in this case */
 | 
				
			||||||
void * FASTCALL __bound_ptr_add(void *p, size_t offset)
 | 
					void * FASTCALL __bound_ptr_add(void *p, size_t offset,
 | 
				
			||||||
 | 
					                                size_t line, const char *filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    size_t addr = (size_t)p;
 | 
					    size_t addr = (size_t)p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,8 +230,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
 | 
				
			||||||
        return p + offset;
 | 
					        return p + offset;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dprintf(stderr, "%s %s: %p 0x%x\n",
 | 
					    dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n",
 | 
				
			||||||
            __FILE__, __FUNCTION__, p, (unsigned)offset);
 | 
					            __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    WAIT_SEM ();
 | 
					    WAIT_SEM ();
 | 
				
			||||||
    INCR_COUNT(bound_ptr_add_count);
 | 
					    INCR_COUNT(bound_ptr_add_count);
 | 
				
			||||||
| 
						 | 
					@ -249,8 +250,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
 | 
				
			||||||
        if (addr <= tree->size) {
 | 
					        if (addr <= tree->size) {
 | 
				
			||||||
            addr += offset;
 | 
					            addr += offset;
 | 
				
			||||||
            if (tree->is_invalid || addr > tree->size) {
 | 
					            if (tree->is_invalid || addr > tree->size) {
 | 
				
			||||||
                fprintf(stderr,"%s %s: %p is outside of the region\n",
 | 
					                fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n",
 | 
				
			||||||
                        __FILE__, __FUNCTION__, p + offset);
 | 
					                        __FILE__, __FUNCTION__, filename, line, p + offset);
 | 
				
			||||||
                if (never_fatal == 0) {
 | 
					                if (never_fatal == 0) {
 | 
				
			||||||
                    POST_SEM ();
 | 
					                    POST_SEM ();
 | 
				
			||||||
                    return INVALID_POINTER; /* return an invalid pointer */
 | 
					                    return INVALID_POINTER; /* return an invalid pointer */
 | 
				
			||||||
| 
						 | 
					@ -265,15 +266,16 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
 | 
				
			||||||
/* return '(p + offset)' for pointer indirection (the resulting must
 | 
					/* return '(p + offset)' for pointer indirection (the resulting must
 | 
				
			||||||
   be strictly inside the region */
 | 
					   be strictly inside the region */
 | 
				
			||||||
#define BOUND_PTR_INDIR(dsize)                                                 \
 | 
					#define BOUND_PTR_INDIR(dsize)                                                 \
 | 
				
			||||||
void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset)         \
 | 
					void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset,            \
 | 
				
			||||||
 | 
					                                            size_t line, const char *filename) \
 | 
				
			||||||
{                                                                              \
 | 
					{                                                                              \
 | 
				
			||||||
    size_t addr = (size_t)p;                                                   \
 | 
					    size_t addr = (size_t)p;                                                   \
 | 
				
			||||||
                                                                               \
 | 
					                                                                               \
 | 
				
			||||||
    if (no_checking) {                                                         \
 | 
					    if (no_checking) {                                                         \
 | 
				
			||||||
        return p + offset;                                                     \
 | 
					        return p + offset;                                                     \
 | 
				
			||||||
    }                                                                          \
 | 
					    }                                                                          \
 | 
				
			||||||
    dprintf(stderr, "%s %s: %p 0x%x start\n",                               \
 | 
					    dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n",                          \
 | 
				
			||||||
            __FILE__, __FUNCTION__, p, (unsigned)offset);                   \
 | 
					            __FILE__, __FUNCTION__, filename, line,  p, (unsigned)offset);     \
 | 
				
			||||||
    WAIT_SEM ();                                                               \
 | 
					    WAIT_SEM ();                                                               \
 | 
				
			||||||
    INCR_COUNT(bound_ptr_indir ## dsize ## _count);                            \
 | 
					    INCR_COUNT(bound_ptr_indir ## dsize ## _count);                            \
 | 
				
			||||||
    if (tree) {                                                                \
 | 
					    if (tree) {                                                                \
 | 
				
			||||||
| 
						 | 
					@ -291,8 +293,8 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset)         \
 | 
				
			||||||
        if (addr <= tree->size) {                                              \
 | 
					        if (addr <= tree->size) {                                              \
 | 
				
			||||||
            addr += offset + dsize;                                            \
 | 
					            addr += offset + dsize;                                            \
 | 
				
			||||||
            if (tree->is_invalid || addr > tree->size) {                       \
 | 
					            if (tree->is_invalid || addr > tree->size) {                       \
 | 
				
			||||||
                fprintf(stderr,"%s %s: %p is outside of the region\n",      \
 | 
					                fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \
 | 
				
			||||||
                    __FILE__, __FUNCTION__, p + offset);                    \
 | 
					                    __FILE__, __FUNCTION__, filename, line, p + offset);       \
 | 
				
			||||||
                if (never_fatal == 0) {                                        \
 | 
					                if (never_fatal == 0) {                                        \
 | 
				
			||||||
                    POST_SEM ();                                               \
 | 
					                    POST_SEM ();                                               \
 | 
				
			||||||
                    return INVALID_POINTER; /* return an invalid pointer */    \
 | 
					                    return INVALID_POINTER; /* return an invalid pointer */    \
 | 
				
			||||||
| 
						 | 
					@ -540,7 +542,7 @@ void __attribute__((destructor)) __bound_exit(void)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        while (tree) {
 | 
					        while (tree) {
 | 
				
			||||||
            if (print_heap && tree->type != 0) {
 | 
					            if (print_heap && tree->type != 0) {
 | 
				
			||||||
                fprintf (stderr, "%s, %s() %s found size %ld\n",
 | 
					                fprintf (stderr, "%s, %s() %s found size %lu\n",
 | 
				
			||||||
                         __FILE__, __FUNCTION__, alloc_type[tree->type],
 | 
					                         __FILE__, __FUNCTION__, alloc_type[tree->type],
 | 
				
			||||||
                         (unsigned long) tree->size);
 | 
					                         (unsigned long) tree->size);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -621,7 +623,7 @@ void *__bound_malloc(size_t size, const void *caller)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ptr) {
 | 
					    if (ptr) {
 | 
				
			||||||
        tree = splay_insert ((size_t) ptr, size, tree);
 | 
					        tree = splay_insert ((size_t) ptr, size, tree);
 | 
				
			||||||
        if (tree->start == (size_t) ptr) {
 | 
					        if (tree && tree->start == (size_t) ptr) {
 | 
				
			||||||
            tree->type = TCC_TYPE_MALLOC;
 | 
					            tree->type = TCC_TYPE_MALLOC;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -666,7 +668,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
 | 
				
			||||||
        dprintf(stderr, "%s, %s (%p, 0x%x)\n",
 | 
					        dprintf(stderr, "%s, %s (%p, 0x%x)\n",
 | 
				
			||||||
                __FILE__, __FUNCTION__, ptr, (unsigned)size);
 | 
					                __FILE__, __FUNCTION__, ptr, (unsigned)size);
 | 
				
			||||||
        tree = splay_insert((size_t) ptr, size, tree);
 | 
					        tree = splay_insert((size_t) ptr, size, tree);
 | 
				
			||||||
        if (tree->start == (size_t) ptr) {
 | 
					        if (tree && tree->start == (size_t) ptr) {
 | 
				
			||||||
            tree->type = TCC_TYPE_MEMALIGN;
 | 
					            tree->type = TCC_TYPE_MEMALIGN;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -744,7 +746,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller)
 | 
				
			||||||
        INCR_COUNT(bound_realloc_count);
 | 
					        INCR_COUNT(bound_realloc_count);
 | 
				
			||||||
        if (ptr) {
 | 
					        if (ptr) {
 | 
				
			||||||
            tree = splay_insert ((size_t) ptr, size, tree);
 | 
					            tree = splay_insert ((size_t) ptr, size, tree);
 | 
				
			||||||
            if (tree->start == (size_t) ptr) {
 | 
					            if (tree && tree->start == (size_t) ptr) {
 | 
				
			||||||
                tree->type = TCC_TYPE_REALLOC;
 | 
					                tree->type = TCC_TYPE_REALLOC;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -761,7 +763,7 @@ void *__bound_realloc(void *ptr, size_t size, const void *caller)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        if (ptr) {
 | 
					        if (ptr) {
 | 
				
			||||||
            tree = splay_insert ((size_t) ptr, size, tree);
 | 
					            tree = splay_insert ((size_t) ptr, size, tree);
 | 
				
			||||||
            if (tree->start == (size_t) ptr) {
 | 
					            if (tree && tree->start == (size_t) ptr) {
 | 
				
			||||||
                tree->type = TCC_TYPE_REALLOC;
 | 
					                tree->type = TCC_TYPE_REALLOC;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -800,7 +802,7 @@ void *__bound_calloc(size_t nmemb, size_t size)
 | 
				
			||||||
        WAIT_SEM ();
 | 
					        WAIT_SEM ();
 | 
				
			||||||
        INCR_COUNT(bound_calloc_count);
 | 
					        INCR_COUNT(bound_calloc_count);
 | 
				
			||||||
        tree = splay_insert ((size_t) ptr, size, tree);
 | 
					        tree = splay_insert ((size_t) ptr, size, tree);
 | 
				
			||||||
        if (tree->start == (size_t) ptr) {
 | 
					        if (tree && tree->start == (size_t) ptr) {
 | 
				
			||||||
            tree->type = TCC_TYPE_CALLOC;
 | 
					            tree->type = TCC_TYPE_CALLOC;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        POST_SEM ();
 | 
					        POST_SEM ();
 | 
				
			||||||
| 
						 | 
					@ -899,13 +901,13 @@ void __bound_new_region(void *p, size_t size)
 | 
				
			||||||
/* some useful checked functions */
 | 
					/* some useful checked functions */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* check that (p ... p + size - 1) lies inside 'p' region, if any */
 | 
					/* check that (p ... p + size - 1) lies inside 'p' region, if any */
 | 
				
			||||||
static void __bound_check(const void *p, size_t size)
 | 
					static void __bound_check(const void *p, size_t size, const char *function)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (no_checking)
 | 
					    if (no_checking)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    if (size == 0)
 | 
					    if (size == 0)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    p = __bound_ptr_add((void *)p, size);
 | 
					    p = __bound_ptr_add((void *)p, size, 0, function);
 | 
				
			||||||
    if (p == INVALID_POINTER)
 | 
					    if (p == INVALID_POINTER)
 | 
				
			||||||
        bound_error("invalid pointer");
 | 
					        bound_error("invalid pointer");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -915,8 +917,8 @@ void *__bound_memcpy(void *dst, const void *src, size_t size)
 | 
				
			||||||
    void* p;
 | 
					    void* p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INCR_COUNT(bound_mempcy_count);
 | 
					    INCR_COUNT(bound_mempcy_count);
 | 
				
			||||||
    __bound_check(dst, size);
 | 
					    __bound_check(dst, size, "memcpy");
 | 
				
			||||||
    __bound_check(src, size);
 | 
					    __bound_check(src, size, "memcpy");
 | 
				
			||||||
    /* check also region overlap */
 | 
					    /* check also region overlap */
 | 
				
			||||||
    if (no_checking == 0 && src >= dst && src < dst + size)
 | 
					    if (no_checking == 0 && src >= dst && src < dst + size)
 | 
				
			||||||
        bound_error("overlapping regions in memcpy()");
 | 
					        bound_error("overlapping regions in memcpy()");
 | 
				
			||||||
| 
						 | 
					@ -929,23 +931,23 @@ void *__bound_memcpy(void *dst, const void *src, size_t size)
 | 
				
			||||||
int __bound_memcmp(const void *s1, const void *s2, size_t size)
 | 
					int __bound_memcmp(const void *s1, const void *s2, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    INCR_COUNT(bound_memcmp_count);
 | 
					    INCR_COUNT(bound_memcmp_count);
 | 
				
			||||||
    __bound_check(s1, size);
 | 
					    __bound_check(s1, size, "memcmp");
 | 
				
			||||||
    __bound_check(s2, size);
 | 
					    __bound_check(s2, size, "memcmp");
 | 
				
			||||||
    return memcmp(s1, s2, size);
 | 
					    return memcmp(s1, s2, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *__bound_memmove(void *dst, const void *src, size_t size)
 | 
					void *__bound_memmove(void *dst, const void *src, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    INCR_COUNT(bound_memmove_count);
 | 
					    INCR_COUNT(bound_memmove_count);
 | 
				
			||||||
    __bound_check(dst, size);
 | 
					    __bound_check(dst, size, "memmove");
 | 
				
			||||||
    __bound_check(src, size);
 | 
					    __bound_check(src, size, "memmove");
 | 
				
			||||||
    return memmove(dst, src, size);
 | 
					    return memmove(dst, src, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *__bound_memset(void *dst, int c, size_t size)
 | 
					void *__bound_memset(void *dst, int c, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    INCR_COUNT(bound_memset_count);
 | 
					    INCR_COUNT(bound_memset_count);
 | 
				
			||||||
    __bound_check(dst, size);
 | 
					    __bound_check(dst, size, "memset");
 | 
				
			||||||
    return memset(dst, c, size);
 | 
					    return memset(dst, c, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -957,7 +959,7 @@ int __bound_strlen(const char *s)
 | 
				
			||||||
    INCR_COUNT(bound_strlen_count);
 | 
					    INCR_COUNT(bound_strlen_count);
 | 
				
			||||||
    while (*p++);
 | 
					    while (*p++);
 | 
				
			||||||
    len = (p - s) - 1;
 | 
					    len = (p - s) - 1;
 | 
				
			||||||
    p = __bound_ptr_indir1((char *)s, len);
 | 
					    p = __bound_ptr_indir1((char *)s, len, 0, "strlen");
 | 
				
			||||||
    if (p == INVALID_POINTER)
 | 
					    if (p == INVALID_POINTER)
 | 
				
			||||||
        bound_error("bad pointer in strlen()");
 | 
					        bound_error("bad pointer in strlen()");
 | 
				
			||||||
    return len;
 | 
					    return len;
 | 
				
			||||||
| 
						 | 
					@ -982,8 +984,8 @@ char *__bound_strncpy(char *dst, const char *src, size_t n)
 | 
				
			||||||
    while (len-- && *p++);
 | 
					    while (len-- && *p++);
 | 
				
			||||||
    len = p - src;
 | 
					    len = p - src;
 | 
				
			||||||
    INCR_COUNT(bound_strncpy_count);
 | 
					    INCR_COUNT(bound_strncpy_count);
 | 
				
			||||||
    __bound_check(dst, len);
 | 
					    __bound_check(dst, len, "strncpy");
 | 
				
			||||||
    __bound_check(src, len);
 | 
					    __bound_check(src, len, "strncpy");
 | 
				
			||||||
    return strncpy (dst, src, n);
 | 
					    return strncpy (dst, src, n);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -997,8 +999,8 @@ int __bound_strcmp(const char *s1, const char *s2)
 | 
				
			||||||
        u1++;
 | 
					        u1++;
 | 
				
			||||||
        u2++;
 | 
					        u2++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    __bound_check(s1, ((const char *)u1 - s1) + 1);
 | 
					    __bound_check(s1, ((const char *)u1 - s1) + 1, "strcmp");
 | 
				
			||||||
    __bound_check(s2, ((const char *)u2 - s2) + 1);
 | 
					    __bound_check(s2, ((const char *)u2 - s2) + 1, "strcmp");
 | 
				
			||||||
    return (*u1 - *u2);
 | 
					    return (*u1 - *u2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1018,8 +1020,8 @@ int __bound_strncmp(const char *s1, const char *s2, size_t n)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        u2++;
 | 
					        u2++;
 | 
				
			||||||
    } while (*u1++);
 | 
					    } while (*u1++);
 | 
				
			||||||
    __bound_check(s1, ((const char *)u1 - s1) + 1);
 | 
					    __bound_check(s1, ((const char *)u1 - s1) + 1, "strncmp");
 | 
				
			||||||
    __bound_check(s2, ((const char *)u1 - s1) + 1);
 | 
					    __bound_check(s2, ((const char *)u1 - s1) + 1, "strncmp");
 | 
				
			||||||
    return retval;
 | 
					    return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1032,8 +1034,8 @@ char *__bound_strcat(char *dest, const char *src)
 | 
				
			||||||
    while (*dest++);
 | 
					    while (*dest++);
 | 
				
			||||||
    dest--;
 | 
					    dest--;
 | 
				
			||||||
    while ((*dest++ = *src++) != 0);
 | 
					    while ((*dest++ = *src++) != 0);
 | 
				
			||||||
    __bound_check(r, dest - r);
 | 
					    __bound_check(r, dest - r, "strcat");
 | 
				
			||||||
    __bound_check(s, src - s);
 | 
					    __bound_check(s, src - s, "strcat");
 | 
				
			||||||
    return r;
 | 
					    return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1049,7 +1051,7 @@ char *__bound_strchr(const char *string, int ch)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        s++;
 | 
					        s++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    __bound_check(string, ((const char *)s - string) + 1);
 | 
					    __bound_check(string, ((const char *)s - string) + 1, "strchr");
 | 
				
			||||||
    return *s == c ? (char *) s : NULL;
 | 
					    return *s == c ? (char *) s : NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1060,7 +1062,7 @@ char *__bound_strdup(const char *s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INCR_COUNT(bound_strdup_count);
 | 
					    INCR_COUNT(bound_strdup_count);
 | 
				
			||||||
    while (*p++);
 | 
					    while (*p++);
 | 
				
			||||||
    __bound_check(s, p - s);
 | 
					    __bound_check(s, p - s, "strdup");
 | 
				
			||||||
#if MALLOC_REDIR
 | 
					#if MALLOC_REDIR
 | 
				
			||||||
    new = malloc_redir (p - s);
 | 
					    new = malloc_redir (p - s);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -1069,7 +1071,7 @@ char *__bound_strdup(const char *s)
 | 
				
			||||||
    if (new) {
 | 
					    if (new) {
 | 
				
			||||||
        WAIT_SEM ();
 | 
					        WAIT_SEM ();
 | 
				
			||||||
        tree = splay_insert((size_t)new, p - s, tree);
 | 
					        tree = splay_insert((size_t)new, p - s, tree);
 | 
				
			||||||
        if (tree->start == (size_t) new) {
 | 
					        if (tree && tree->start == (size_t) new) {
 | 
				
			||||||
            tree->type = TCC_TYPE_STRDUP;
 | 
					            tree->type = TCC_TYPE_STRDUP;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        memcpy (new, s, p - s);
 | 
					        memcpy (new, s, p - s);
 | 
				
			||||||
| 
						 | 
					@ -1261,7 +1263,10 @@ static Tree * splay_insert(size_t addr, size_t size, Tree * t)
 | 
				
			||||||
        new = (Tree *) malloc (sizeof (Tree));
 | 
					        new = (Tree *) malloc (sizeof (Tree));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (new == NULL) {bound_alloc_error();}
 | 
					    if (new == NULL) {
 | 
				
			||||||
 | 
					      bound_alloc_error();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
        if (t == NULL) {
 | 
					        if (t == NULL) {
 | 
				
			||||||
            new->left = new->right = NULL;
 | 
					            new->left = new->right = NULL;
 | 
				
			||||||
        } else if (compare(addr, t->start, t->size) < 0) {
 | 
					        } else if (compare(addr, t->start, t->size) < 0) {
 | 
				
			||||||
| 
						 | 
					@ -1277,6 +1282,7 @@ static Tree * splay_insert(size_t addr, size_t size, Tree * t)
 | 
				
			||||||
        new->size = size;
 | 
					        new->size = size;
 | 
				
			||||||
        new->type = TCC_TYPE_NONE;
 | 
					        new->type = TCC_TYPE_NONE;
 | 
				
			||||||
        new->is_invalid = 0;
 | 
					        new->is_invalid = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return new;
 | 
					    return new;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										57
									
								
								x86_64-gen.c
									
										
									
									
									
								
							
							
						
						
									
										57
									
								
								x86_64-gen.c
									
										
									
									
									
								
							| 
						 | 
					@ -767,28 +767,12 @@ ST_FUNC void gen_bounded_ptr_add(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (nested_call > 1) {
 | 
					    if (nested_call > 1) {
 | 
				
			||||||
#ifdef TCC_TARGET_PE
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
        o(0x5152);   /* push %rcx/%rdx */
 | 
					        o(0x5152);       /* push %rdx/%rcx */
 | 
				
			||||||
 | 
					        o(0x51415041);   /* push %r8/%r9 */
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        o(0x5657);   /* push %rdi/%rsi */
 | 
					        o(0x51525657);   /* push %rdi/%rsi/%rdx/%rcx */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* trick to get line/file_name in code */
 | 
					 | 
				
			||||||
    o(0xb8);
 | 
					 | 
				
			||||||
    gen_le32 (file->line_num);
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        int len;
 | 
					 | 
				
			||||||
        char *cp = file->filename;
 | 
					 | 
				
			||||||
        while (*cp) cp++;
 | 
					 | 
				
			||||||
        while (cp != file->filename && cp[-1] != '/') cp--;
 | 
					 | 
				
			||||||
        len = strlen (cp);
 | 
					 | 
				
			||||||
        while (len > 0) {
 | 
					 | 
				
			||||||
            memcpy (&i, cp, 4);
 | 
					 | 
				
			||||||
            o(0xb8);
 | 
					 | 
				
			||||||
            gen_le32 (i);
 | 
					 | 
				
			||||||
            cp += 4;
 | 
					 | 
				
			||||||
            len -= 4;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /* prepare fast x86_64 function call */
 | 
					    /* prepare fast x86_64 function call */
 | 
				
			||||||
    gv(RC_RAX);
 | 
					    gv(RC_RAX);
 | 
				
			||||||
#ifdef TCC_TARGET_PE
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
| 
						 | 
					@ -806,6 +790,38 @@ ST_FUNC void gen_bounded_ptr_add(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    vtop--;
 | 
					    vtop--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* add line, filename */
 | 
				
			||||||
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
 | 
					    o(0xc0c749);   /* mov $xx,%r8 */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    o(0xba);       /* mov $xx,%edx */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    gen_le32 (file->line_num);
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        static addr_t offset;
 | 
				
			||||||
 | 
					        static char last_filename[1024];
 | 
				
			||||||
 | 
					        Sym *sym_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (strcmp (last_filename, file->filename) != 0) {
 | 
				
			||||||
 | 
					            void *ptr;
 | 
				
			||||||
 | 
					            int len = strlen (file->filename) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            offset = data_section->data_offset;
 | 
				
			||||||
 | 
					            ptr = section_ptr_add(data_section, len);
 | 
				
			||||||
 | 
					            memcpy (ptr, file->filename, len);
 | 
				
			||||||
 | 
					            memcpy (last_filename, file->filename, len);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
 | 
					        o(0xb949);   /* mov $xx,%r9 */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        o(0xb948);   /* mov $xx,%rcx */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        gen_le64 (0);
 | 
				
			||||||
 | 
					        sym_data = get_sym_ref(&char_pointer_type, data_section,
 | 
				
			||||||
 | 
					                               offset, data_section->data_offset);
 | 
				
			||||||
 | 
					        greloca(cur_text_section, sym_data, ind - 8, R_X86_64_64, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TCC_TARGET_PE
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
    o(0x20ec8348); /* sub $20, %rsp */
 | 
					    o(0x20ec8348); /* sub $20, %rsp */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -819,9 +835,10 @@ ST_FUNC void gen_bounded_ptr_add(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (nested_call > 1) {
 | 
					    if (nested_call > 1) {
 | 
				
			||||||
#ifdef TCC_TARGET_PE
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
 | 
					        o(0x58415941);   /* pop %r9/%r8 */
 | 
				
			||||||
        o(0x5a59);       /* pop %rcx/%rdx */
 | 
					        o(0x5a59);       /* pop %rcx/%rdx */
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        o(0x5f5e);   /* pop %rsi/%rdi */
 | 
					        o(0x5f5e5a59);   /* pop $rcx/%rdx/%rsi/%rdi */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* returned pointer is in rax */
 | 
					    /* returned pointer is in rax */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue