I tried bound checking with tcc and found some problems. (See attached patch).

First the bounds checking code is included in shared objects and in the application.
This means that for example malloc and friends are redirected twice.
I fixed this in tccelf.c

Second problem is that only arrays are checked.
But there are a lot of other objects like structs with arrays or variables with address taken that should also work.
Fixed this in tccgen.c

The last one is some problems with code generation on x86_64.
The difficult one was the VT_LLOCAL code.
Fixed in x86_64-gen.c

I will stop now because bounds checking looks not to work for complex applications.

Perhaps we could add the above code to git? The first and last one are fixing problems. For the last problem I have a testcase that reproduces the VT_LLOCAL problem.

Regards,

    Herman
diff --git a/tccelf.c b/tccelf.c
index 8644005..ca9329e 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -1514,7 +1514,8 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
                 tcc_add_dll(s1, TCC_LIBGCC, 0);
         }
 #endif
-        tcc_add_support(s1, TCC_LIBTCC1);
+        if (s1->output_type != TCC_OUTPUT_DLL)
+            tcc_add_support(s1, TCC_LIBTCC1);
         /* add crt end if not memory output */
         if (s1->output_type != TCC_OUTPUT_MEMORY)
             tcc_add_crt(s1, "crtn.o");
@@ -2964,6 +2965,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int 
size, int entrysize)
     const char *ar_names, *p;
     const uint8_t *ar_index;
     ElfW(Sym) *sym;
+    Section *s;
 
     data = tcc_malloc(size);
     if (full_read(fd, data, size) != size)
@@ -2975,9 +2977,14 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int 
size, int entrysize)
     do {
         bound = 0;
         for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
-            sym_index = find_elf_sym(symtab_section, p);
+            s = symtab_section;
+            sym_index = find_elf_sym(s, p);
+            if(sym_index == 0) {
+                s = s1->dynsymtab_section;
+                sym_index = find_elf_sym(s, p);
+            }
             if(sym_index) {
-                sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                sym = &((ElfW(Sym) *)s->data)[sym_index];
                 if(sym->st_shndx == SHN_UNDEF) {
                     off = (entrysize == 4
                           ? get_be32(ar_index + i * 4)
diff --git a/tccgen.c b/tccgen.c
index a6181b0..952beb5 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -7422,8 +7422,10 @@ static void decl_initializer_alloc(CType *type, 
AttributeDef *ad, int r,
 #ifdef CONFIG_TCC_BCHECK
         /* handles bounds */
         /* XXX: currently, since we do only one pass, we cannot track
-           '&' operators, so we add only arrays */
-        if (bcheck && (type->t & VT_ARRAY)) {
+           '&' operators, so we add only arrays.
+          Add all values because address could be taken or
+           a struct/union could contain an array. */
+        if (bcheck /*  && (type->t & VT_ARRAY) */) {
             addr_t *bounds_ptr;
             /* add padding between regions */
             loc--;
diff --git a/x86_64-gen.c b/x86_64-gen.c
index cc66b60..0c5b1a7 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -645,7 +645,11 @@ static void gen_static_call(int v)
 {
     Sym *sym = external_global_sym(v, &func_old_type);
     oad(0xe8, 0);
+#ifdef TCC_TARGET_PE
     greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
+#else
+    greloca(cur_text_section, sym, ind-4, R_X86_64_PLT32, -4);
+#endif
 }
 
 /* generate a bounded pointer addition */
@@ -1574,7 +1578,8 @@ void gfunc_prolog(CType *func_type)
     if (tcc_state->do_bounds_check) {
         func_bound_offset = lbounds_section->data_offset;
         func_bound_ind = ind;
-        oad(0xb8, 0); /* lbound section pointer */
+        o(0xb848); /* lbound section pointer */
+        gen_le64 (0);
        o(0xc78948);  /* mov  %rax,%rdi ## first arg in %rdi, this must be ptr 
*/
        oad(0xb8, 0); /* call to function */
     }
@@ -1603,15 +1608,16 @@ void gfunc_epilog(void)
                                func_bound_offset, 
lbounds_section->data_offset);
         saved_ind = ind;
         ind = func_bound_ind;
-        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
-        ind = ind + 5 + 3;
+        greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
+        ind = ind + 10 + 3;
         gen_static_call(TOK___bound_local_new);
         ind = saved_ind;
 
         /* generate bound check local freeing */
         o(0x5250); /* save returned value, if any */
-        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
-        oad(0xb8, 0); /* mov xxx, %rax */
+        greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
+        o(0xb848); /* mov xxx, %rax */
+        gen_le64 (0);
         o(0xc78948);  /* mov %rax,%rdi # first arg in %rdi, this must be ptr */
         gen_static_call(TOK___bound_local_delete);
         o(0x585a); /* restore returned value, if any */
@@ -1934,12 +1940,13 @@ void gen_opf(int op)
             fc = vtop->c.i;
             if ((r & VT_VALMASK) == VT_LLOCAL) {
                 SValue v1;
-                r = get_reg(RC_INT);
+                r = get_reg(RC_FLOAT);
                 v1.type.t = VT_PTR;
                 v1.r = VT_LOCAL | VT_LVAL;
                 v1.c.i = fc;
                 load(r, &v1);
                 fc = 0;
+                vtop->r = r = r | VT_LVAL;
             }
 
             if (op == TOK_EQ || op == TOK_NE) {
@@ -2001,12 +2008,13 @@ void gen_opf(int op)
             /* if saved lvalue, then we must reload it */
             if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
                 SValue v1;
-                r = get_reg(RC_INT);
+                r = get_reg(RC_FLOAT);
                 v1.type.t = VT_PTR;
                 v1.r = VT_LOCAL | VT_LVAL;
                 v1.c.i = fc;
                 load(r, &v1);
                 fc = 0;
+                vtop->r = r = r | VT_LVAL;
             }
             
             assert(!(vtop[-1].r & VT_LVAL));
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to