History

tccgen: x86_64: fix garbage in the SValue upper bits

This was going wrong (case TOK_LAND in unary: computed labels) - vset(&s->type, VT_CONST | VT_SYM, 0); - vtop->sym = s; This does the right thing and is shorter: + vpushsym(&s->type, s); Test case was: int main(int argc, char **argv) { int x; static void *label_return = &&lbl_return; printf("label_return = %p\n", label_return); goto *label_return; //<<<<< here segfault on linux X86_64 without the memset on vset printf("unreachable\n"); lbl_return: return 0; } Also:: - Rename "void* CValue.ptr" to more usable "addr_t ptr_offset" and start to use it in obvious cases. - use __attribute__ ((noreturn)) only with gnu compiler - Revert CValue memsets ("After several days searching ...") commit 4bc83ac3933efa565ae3326b55fcd711b63c073d Doesn't mean that the vsetX/vpush thingy isn't brittle and there still might be bugs as to differences in how the CValue union was set and is then interpreted later on. However the big memset hammer was just too slow (-3% overall).

grischka committed 12 years ago

Commit 5879c851 parent 2024c443 files · +52 −70Browse files

Unified · Split

3 files
  1. tcc.h +39 −37
  2. tccgen.c +9 −21
  3. tccpp.c +4 −12
tcc.h+39−37
@@ -55,18 +55,27 @@ · 54 unmodified lines
55# ifndef CONFIG_TCC_STATIC55# ifndef CONFIG_TCC_STATIC
56# include <dlfcn.h>56# include <dlfcn.h>
57# endif57# endif
58#else58/* XXX: need to define this to use them in non ISOC99 context */
59 extern float strtof (const char *__nptr, char **__endptr);
60 extern long double strtold (const char *__nptr, char **__endptr);
61#else /* on _WIN32: */
59# include <windows.h>62# include <windows.h>
60# include <sys/timeb.h>63# include <sys/timeb.h>
61# include <io.h> /* open, close etc. */64# include <io.h> /* open, close etc. */
62# include <direct.h> /* getcwd */65# include <direct.h> /* getcwd */
63# ifdef __GNUC__66# ifdef __GNUC__
64# include <stdint.h>67# include <stdint.h>
65# else
66 typedef UINT_PTR uintptr_t;
67# endif68# endif
68# define inline __inline69# define inline __inline
69# define inp next_inp70# define inp next_inp
71# define snprintf _snprintf
72# define vsnprintf _vsnprintf
73# ifndef __GNUC__
74# define strtold (long double)strtod
75# define strtof (float)strtod
76# define strtoll _strtoi64
77# define strtoull _strtoui64
78# endif
70# ifdef LIBTCC_AS_DLL79# ifdef LIBTCC_AS_DLL
71# define LIBTCCAPI __declspec(dllexport)80# define LIBTCCAPI __declspec(dllexport)
72# define PUB_FUNC LIBTCCAPI81# define PUB_FUNC LIBTCCAPI
@@ -79,6 +88,30 @@ · 6 unmodified lines
79# define O_BINARY 088# define O_BINARY 0
80#endif89#endif
81 90
91#ifdef __GNUC__
92# define NORETURN __attribute__ ((noreturn))
93#elif defined _MSC_VER
94# define NORETURN __declspec(noreturn)
95#else
96# define NORETURN
97#endif
98
99#ifdef _WIN32
100# define IS_DIRSEP(c) (c == '/' || c == '\\')
101# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
102# define PATHCMP stricmp
103#else
104# define IS_DIRSEP(c) (c == '/')
105# define IS_ABSPATH(p) IS_DIRSEP(p[0])
106# define PATHCMP strcmp
107#endif
108
109#ifdef TCC_TARGET_PE
110#define PATHSEP ';'
111#else
112#define PATHSEP ':'
113#endif
114
82#include "elf.h"115#include "elf.h"
83#ifdef TCC_TARGET_X86_64116#ifdef TCC_TARGET_X86_64
84# define ELFCLASSW ELFCLASS64117# define ELFCLASSW ELFCLASS64
@@ -315,7 +348,7 @@ typedef union CValue { · 230 unmodified lines
315 long long ll;348 long long ll;
316 unsigned long long ull;349 unsigned long long ull;
317 struct CString *cstr;350 struct CString *cstr;
318 void *ptr;351 addr_t ptr_offset;
319 int tab[LDOUBLE_SIZE/4];352 int tab[LDOUBLE_SIZE/4];
320} CValue;353} CValue;
321 354
@@ -938,37 +971,6 @@ enum tcc_token { · 616 unmodified lines
938 971
939#define TOK_UIDENT TOK_DEFINE972#define TOK_UIDENT TOK_DEFINE
940 973
941#ifdef _WIN32
942#define snprintf _snprintf
943#define vsnprintf _vsnprintf
944#ifndef __GNUC__
945# define strtold (long double)strtod
946# define strtof (float)strtod
947# define strtoll _strtoi64
948# define strtoull _strtoui64
949#endif
950#else
951/* XXX: need to define this to use them in non ISOC99 context */
952extern float strtof (const char *__nptr, char **__endptr);
953extern long double strtold (const char *__nptr, char **__endptr);
954#endif
955
956#ifdef _WIN32
957#define IS_DIRSEP(c) (c == '/' || c == '\\')
958#define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
959#define PATHCMP stricmp
960#else
961#define IS_DIRSEP(c) (c == '/')
962#define IS_ABSPATH(p) IS_DIRSEP(p[0])
963#define PATHCMP strcmp
964#endif
965
966#ifdef TCC_TARGET_PE
967#define PATHSEP ';'
968#else
969#define PATHSEP ':'
970#endif
971
972/* space exlcuding newline */974/* space exlcuding newline */
973static inline int is_space(int ch)975static inline int is_space(int ch)
974{976{
@@ -1045,7 +1047,7 @@ PUB_FUNC char *tcc_strdup(const char *str); · 70 unmodified lines
1045#define strdup(s) use_tcc_strdup(s)1047#define strdup(s) use_tcc_strdup(s)
1046PUB_FUNC void tcc_memstats(void);1048PUB_FUNC void tcc_memstats(void);
1047PUB_FUNC void tcc_error_noabort(const char *fmt, ...);1049PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
1048PUB_FUNC void tcc_error(const char *fmt, ...) __attribute__ ((noreturn));1050PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
1049PUB_FUNC void tcc_warning(const char *fmt, ...);1051PUB_FUNC void tcc_warning(const char *fmt, ...);
1050 1052
1051/* other utilities */1053/* other utilities */
@@ -1143,7 +1145,7 @@ ST_FUNC void preprocess_init(TCCState *s1); · 91 unmodified lines
1143ST_FUNC void preprocess_new(void);1145ST_FUNC void preprocess_new(void);
1144ST_FUNC int tcc_preprocess(TCCState *s1);1146ST_FUNC int tcc_preprocess(TCCState *s1);
1145ST_FUNC void skip(int c);1147ST_FUNC void skip(int c);
1146ST_FUNC void expect(const char *msg) __attribute__ ((noreturn));1148ST_FUNC NORETURN void expect(const char *msg);
1147 1149
1148/* ------------ tccgen.c ------------ */1150/* ------------ tccgen.c ------------ */
1149 1151
tccgen.c+9−21
@@ -329,7 +329,6 @@ static void vsetc(CType *type, int r, CValue *vc) · 328 unmodified lines
329void vpush(CType *type)329void vpush(CType *type)
330{330{
331 CValue cval;331 CValue cval;
332 memset(&cval, 0, sizeof(CValue));
333 vsetc(type, VT_CONST, &cval);332 vsetc(type, VT_CONST, &cval);
334}333}
335 334
@@ -337,29 +336,23 @@ void vpush(CType *type) · 1 unmodified line
337ST_FUNC void vpushi(int v)336ST_FUNC void vpushi(int v)
338{337{
339 CValue cval;338 CValue cval;
340 memset(&cval, 0, sizeof(CValue));
341 cval.i = v;339 cval.i = v;
342 vsetc(&int_type, VT_CONST, &cval);340 vsetc(&int_type, VT_CONST, &cval);
343}341}
344 342
345/* push a pointer sized constant */343/* push a pointer sized constant */
346static void vpushs(long long v)344static void vpushs(addr_t v)
347{345{
348 CValue cval;346 CValue cval;
349 memset(&cval, 0, sizeof(CValue));347 cval.ptr_offset = v;
350 if (PTR_SIZE == 4)
351 cval.i = (int)v;
352 else
353 cval.ull = v;
354 vsetc(&size_type, VT_CONST, &cval);348 vsetc(&size_type, VT_CONST, &cval);
355}349}
356 350
357/* push arbitrary 64bit constant */351/* push arbitrary 64bit constant */
358void vpush64(int ty, unsigned long long v)352void vpush64(int ty, unsigned long long v)
359{353{
360 CType ctype;
361 CValue cval;354 CValue cval;
362 memset(&cval, 0, sizeof(CValue));355 CType ctype;
363 ctype.t = ty;356 ctype.t = ty;
364 ctype.ref = NULL;357 ctype.ref = NULL;
365 cval.ull = v;358 cval.ull = v;
@@ -376,9 +369,7 @@ static inline void vpushll(long long v) · 10 unmodified lines
376static inline void vpushsym(CType *type, Sym *sym)369static inline void vpushsym(CType *type, Sym *sym)
377{370{
378 CValue cval;371 CValue cval;
379 memset(&cval, 0, sizeof(CValue));372 cval.ptr_offset = 0;
380
381 cval.ull = 0;
382 vsetc(type, VT_CONST | VT_SYM, &cval);373 vsetc(type, VT_CONST | VT_SYM, &cval);
383 vtop->sym = sym;374 vtop->sym = sym;
384}375}
@@ -451,7 +442,6 @@ ST_FUNC void vpush_global_sym(CType *type, int v) · 66 unmodified lines
451ST_FUNC void vset(CType *type, int r, int v)442ST_FUNC void vset(CType *type, int r, int v)
452{443{
453 CValue cval;444 CValue cval;
454 memset(&cval, 0, sizeof(CValue));
455 445
456 cval.i = v;446 cval.i = v;
457 vsetc(type, r, &cval);447 vsetc(type, r, &cval);
@@ -737,7 +727,6 @@ ST_FUNC int gv(int rc) · 279 unmodified lines
737 unsigned long offset;727 unsigned long offset;
738#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)728#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
739 CValue check;729 CValue check;
740 memset(&check, 0, sizeof(CValue));
741#endif730#endif
742 731
743 /* XXX: unify with initializers handling ? */732 /* XXX: unify with initializers handling ? */
@@ -770,7 +759,7 @@ ST_FUNC int gv(int rc) · 26 unmodified lines
770 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);759 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
771 vtop->r |= VT_LVAL | VT_SYM;760 vtop->r |= VT_LVAL | VT_SYM;
772 vtop->sym = sym;761 vtop->sym = sym;
773 vtop->c.ull = 0;762 vtop->c.ptr_offset = 0;
774 }763 }
775#ifdef CONFIG_TCC_BCHECK764#ifdef CONFIG_TCC_BCHECK
776 if (vtop->r & VT_MUSTBOUND) 765 if (vtop->r & VT_MUSTBOUND)
@@ -1581,7 +1570,7 @@ static inline int is_null_pointer(SValue *p) · 804 unmodified lines
1581 return 0;1570 return 0;
1582 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||1571 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1583 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||1572 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1584 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);1573 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
1585}1574}
1586 1575
1587static inline int is_integer_btype(int bt)1576static inline int is_integer_btype(int bt)
@@ -3886,8 +3875,7 @@ ST_FUNC void unary(void) · 2298 unmodified lines
3886 mk_pointer(&s->type);3875 mk_pointer(&s->type);
3887 s->type.t |= VT_STATIC;3876 s->type.t |= VT_STATIC;
3888 }3877 }
3889 vset(&s->type, VT_CONST | VT_SYM, 0);3878 vpushsym(&s->type, s);
3890 vtop->sym = s;
3891 next();3879 next();
3892 break;3880 break;
3893 3881
@@ -3939,7 +3927,7 @@ ST_FUNC void unary(void) · 45 unmodified lines
3939 /* if forward reference, we must point to s */3927 /* if forward reference, we must point to s */
3940 if (vtop->r & VT_SYM) {3928 if (vtop->r & VT_SYM) {
3941 vtop->sym = s;3929 vtop->sym = s;
3942 vtop->c.ull = 0;3930 vtop->c.ptr_offset = 0;
3943 }3931 }
3944 break;3932 break;
3945 }3933 }
@@ -5157,7 +5145,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c, · 1211 unmodified lines
5157 if (vtop->r & VT_SYM) {5145 if (vtop->r & VT_SYM) {
5158 greloc(sec, vtop->sym, c, R_DATA_PTR);5146 greloc(sec, vtop->sym, c, R_DATA_PTR);
5159 }5147 }
5160 *(addr_t *)ptr |= (vtop->c.ull & bit_mask) << bit_pos;5148 *(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
5161 break;5149 break;
5162 default:5150 default:
5163 if (vtop->r & VT_SYM) {5151 if (vtop->r & VT_SYM) {
tccpp.c+4−12
@@ -974,7 +974,6 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 973 unmodified lines
974ST_FUNC void tok_str_add_tok(TokenString *s)974ST_FUNC void tok_str_add_tok(TokenString *s)
975{975{
976 CValue cval;976 CValue cval;
977 memset(&cval, 0, sizeof(CValue));
978 977
979 /* save line number info */978 /* save line number info */
980 if (file->line_num != s->last_line_num) {979 if (file->line_num != s->last_line_num) {
@@ -1038,9 +1037,8 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 57 unmodified lines
1038static int macro_is_equal(const int *a, const int *b)1037static int macro_is_equal(const int *a, const int *b)
1039{1038{
1040 char buf[STRING_MAX_SIZE + 1];1039 char buf[STRING_MAX_SIZE + 1];
1041 int t;
1042 CValue cv;1040 CValue cv;
1043 memset(&cv, 0, sizeof(CValue));1041 int t;
1044 while (*a && *b) {1042 while (*a && *b) {
1045 TOK_GET(&t, &a, &cv);1043 TOK_GET(&t, &a, &cv);
1046 pstrcpy(buf, sizeof buf, get_tok_str(t, &cv));1044 pstrcpy(buf, sizeof buf, get_tok_str(t, &cv));
@@ -1199,7 +1197,6 @@ static void tok_print(int *str) · 152 unmodified lines
1199{1197{
1200 int t;1198 int t;
1201 CValue cval;1199 CValue cval;
1202 memset(&cval, 0, sizeof(CValue));
1203 1200
1204 printf("<");1201 printf("<");
1205 while (1) {1202 while (1) {
@@ -2566,10 +2563,9 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 1360 unmodified lines
2566 int last_tok, t, spc;2563 int last_tok, t, spc;
2567 const int *st;2564 const int *st;
2568 Sym *s;2565 Sym *s;
2566 CValue cval;
2569 TokenString str;2567 TokenString str;
2570 CString cstr;2568 CString cstr;
2571 CValue cval;
2572 memset(&cval, 0, sizeof(CValue));
2573 2569
2574 tok_str_new(&str);2570 tok_str_new(&str);
2575 last_tok = 0;2571 last_tok = 0;
@@ -2671,10 +2667,9 @@ static int macro_subst_tok(TokenString *tok_str, · 95 unmodified lines
2671 const int *p;2667 const int *p;
2672 TokenString str;2668 TokenString str;
2673 char *cstrval;2669 char *cstrval;
2670 CValue cval;
2674 CString cstr;2671 CString cstr;
2675 char buf[32];2672 char buf[32];
2676 CValue cval;
2677 memset(&cval, 0, sizeof(CValue));
2678 2673
2679 /* if symbol is a macro, prepare substitution */2674 /* if symbol is a macro, prepare substitution */
2680 /* special macros */2675 /* special macros */
@@ -2849,7 +2844,6 @@ static inline int *macro_twosharps(const int *macro_str) · 168 unmodified lines
2849 /* we search the first '##' */2844 /* we search the first '##' */
2850 for(ptr = macro_str;;) {2845 for(ptr = macro_str;;) {
2851 CValue cval;2846 CValue cval;
2852 memset(&cval, 0, sizeof(CValue));
2853 TOK_GET(&t, &ptr, &cval);2847 TOK_GET(&t, &ptr, &cval);
2854 if (t == TOK_TWOSHARPS)2848 if (t == TOK_TWOSHARPS)
2855 break;2849 break;
@@ -2880,7 +2874,6 @@ static inline int *macro_twosharps(const int *macro_str) · 24 unmodified lines
2880 t = *++ptr;2874 t = *++ptr;
2881 if (t && t != TOK_TWOSHARPS) {2875 if (t && t != TOK_TWOSHARPS) {
2882 CValue cval;2876 CValue cval;
2883 memset(&cval, 0, sizeof(CValue));
2884 TOK_GET(&t, &ptr, &cval);2877 TOK_GET(&t, &ptr, &cval);
2885 /* We concatenate the two tokens */2878 /* We concatenate the two tokens */
2886 cstr_new(&cstr);2879 cstr_new(&cstr);
@@ -2922,10 +2915,9 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 35 unmodified lines
2922 int *macro_str1;2915 int *macro_str1;
2923 const int *ptr;2916 const int *ptr;
2924 int t, ret, spc;2917 int t, ret, spc;
2918 CValue cval;
2925 struct macro_level ml;2919 struct macro_level ml;
2926 int force_blank;2920 int force_blank;
2927 CValue cval;
2928 memset(&cval, 0, sizeof(CValue));
2929 2921
2930 /* first scan for '##' operator handling */2922 /* first scan for '##' operator handling */
2931 ptr = macro_str;2923 ptr = macro_str;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t