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);
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
