Hi there,

when packaging TinyCC 0.9.26 for Debian I noticed a build failure on arm with 
EABI calling convention. A bit puzzled at the failure after all the testing 
done (this bug didn't show up on my hardware), I then started to investigate.

After some look at the code, I asked for help to fellow Debian Developers and 
one quickly found that the problem came from the lack of flushing of 
instruction and data caches before running a program in the -run mode. I then 
quickly started working on a patch but I needed to know the size of the code 
that was compiled by tcc. So I added a function to return this in tccgen.c but 
I'm not sure it's ok. It adds another public function and it's the only 
function that take a TCCState argument in that file.

I'm thus asking for comments on the patch.

Best regards,

Thomas
diff --git a/lib/libtcc1.c b/lib/libtcc1.c
index dacee28..bfe683b 100644
--- a/lib/libtcc1.c
+++ b/lib/libtcc1.c
@@ -689,3 +689,14 @@ void __va_end(struct __va_list_struct *ap)
 }
 
 #endif /* __x86_64__ */
+
+/* Flushing for tccrun */
+#if defined(__x86_64__) || defined(__i386__)
+
+void __clear_cache(char *beginning, char *end)
+{
+}
+
+#else
+#warning __clear_cache not defined for this architecture, avoid using tcc -run
+#endif
diff --git a/tcc.c b/tcc.c
index 52638ef..79f72cc 100644
--- a/tcc.c
+++ b/tcc.c
@@ -321,6 +321,7 @@ int main(int argc, char **argv)
                 first_file = filename;
         }
     }
+    s->phase = 1; /* Compilation is finished */
 
     if (0 == ret) {
         if (bench)
diff --git a/tcc.h b/tcc.h
index e94f91f..0725900 100644
--- a/tcc.h
+++ b/tcc.h
@@ -560,6 +560,7 @@ struct TCCState {
 #ifdef TCC_TARGET_I386
     int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
 #endif
+    int phase; /* phase of the run: 0 while compiling, 1 for link & run */
 
     /* array of all loaded dlls (including those referenced by loaded dlls) */
     DLLReference **loaded_dlls;
@@ -1195,6 +1196,7 @@ ST_FUNC void expr_sum(void);
 ST_FUNC void gexpr(void);
 ST_FUNC int expr_const(void);
 ST_FUNC void gen_inline_functions(void);
+ST_FUNC int get_code_size(TCCState *s);
 ST_FUNC void decl(int l);
 #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
diff --git a/tccgen.c b/tccgen.c
index 0a6250c..874b7aa 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5508,6 +5508,13 @@ static void func_decl_list(Sym *func_sym)
     }
 }
 
+ST_FUNC int get_code_size(TCCState *s)
+{
+    if (s->phase)
+        return text_section->data_offset;
+    return 0;
+}
+
 /* parse a function defined by symbol 'sym' and generate its code in
    'cur_text_section' */
 static void gen_function(Sym *sym)
diff --git a/tccrun.c b/tccrun.c
index 50178a8..32f765c 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -106,6 +106,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
     }
 #endif
 
+    __clear_cache(prog_main, prog_main + get_code_size(s1));
+
 #ifdef CONFIG_TCC_BCHECK
     if (s1->do_bounds_check) {
         void (*bound_init)(void);

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to