From c025478d7c03eb8d32022f1aec4537bd0a75a743 Mon Sep 17 00:00:00 2001 From: mingodad Date: Fri, 28 Mar 2014 20:28:19 +0000 Subject: [PATCH] New implementation of va_list/va_start/var_copy that do not use dynamic memory, with this when compiling fossil-scm with tcc on linux X86_64 it works fine. --- include/stdarg.h | 28 +++++++++++++++++++--------- lib/libtcc1.c | 30 +++++++++--------------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/include/stdarg.h b/include/stdarg.h index 3c1318e..b6a30f7 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -4,18 +4,28 @@ #ifdef __x86_64__ #ifndef _WIN64 -typedef void *va_list; +//This should be in sync with the declaration on our lib/libtcc1.c +/* GCC compatible definition of va_list. */ +typedef struct { + unsigned int gp_offset; + unsigned int fp_offset; + union { + unsigned int overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; +} __va_list_struct; -va_list __va_start(void *fp); -void *__va_arg(va_list ap, int arg_type, int size, int align); -va_list __va_copy(va_list src); -void __va_end(va_list ap); +typedef __va_list_struct va_list; -#define va_start(ap, last) ((ap) = __va_start(__builtin_frame_address(0))) +void __va_start(__va_list_struct *ap, void *fp); +void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); + +#define va_start(ap, last) __va_start(&ap, __builtin_frame_address(0)) #define va_arg(ap, type) \ - (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type)))) -#define va_copy(dest, src) ((dest) = __va_copy(src)) -#define va_end(ap) __va_end(ap) + (*(type *)(__va_arg(&ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type)))) +#define va_copy(dest, src) ((dest) = (src)) +#define va_end(ap) #else /* _WIN64 */ typedef char *va_list; diff --git a/lib/libtcc1.c b/lib/libtcc1.c index a5896a4..284965e 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -626,10 +626,12 @@ long long __fixxfdi (long double a1) #ifndef __TINYC__ #include #include +#include #else /* Avoid including stdlib.h because it is not easily available when cross compiling */ extern void *malloc(unsigned long long); +void *memset(void *s, int c, size_t n); extern void free(void*); extern void abort(void); #endif @@ -638,8 +640,9 @@ enum __va_arg_type { __va_gen_reg, __va_float_reg, __va_stack }; +//This should be in sync with the declaration on our include/stdarg.h /* GCC compatible definition of va_list. */ -struct __va_list_struct { +typedef struct { unsigned int gp_offset; unsigned int fp_offset; union { @@ -647,24 +650,22 @@ struct __va_list_struct { char *overflow_arg_area; }; char *reg_save_area; -}; +} __va_list_struct; #undef __va_start #undef __va_arg #undef __va_copy #undef __va_end -void *__va_start(void *fp) +void __va_start(__va_list_struct *ap, void *fp) { - struct __va_list_struct *ap = - (struct __va_list_struct *)malloc(sizeof(struct __va_list_struct)); - *ap = *(struct __va_list_struct *)((char *)fp - 16); + memset(ap, 0, sizeof(__va_list_struct)); + *ap = *(__va_list_struct *)((char *)fp - 16); ap->overflow_arg_area = (char *)fp + ap->overflow_offset; ap->reg_save_area = (char *)fp - 176 - 16; - return ap; } -void *__va_arg(struct __va_list_struct *ap, +void *__va_arg(__va_list_struct *ap, enum __va_arg_type arg_type, int size, int align) { @@ -701,19 +702,6 @@ void *__va_arg(struct __va_list_struct *ap, } } -void *__va_copy(struct __va_list_struct *src) -{ - struct __va_list_struct *dest = - (struct __va_list_struct *)malloc(sizeof(struct __va_list_struct)); - *dest = *src; - return dest; -} - -void __va_end(struct __va_list_struct *ap) -{ - free(ap); -} - #endif /* __x86_64__ */ /* Flushing for tccrun */