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
5555 # ifndef CONFIG_TCC_STATIC
5656 # include <dlfcn.h>
5757 # endif
58−#else
58+/* 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: */
5962 # include <windows.h>
6063 # include <sys/timeb.h>
6164 # include <io.h> /* open, close etc. */
6265 # include <direct.h> /* getcwd */
6366 # ifdef __GNUC__
6467 # include <stdint.h>
65−# else
66− typedef UINT_PTR uintptr_t;
6768 # endif
6869 # define inline __inline
6970 # 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
7079 # ifdef LIBTCC_AS_DLL
7180 # define LIBTCCAPI __declspec(dllexport)
7281 # define PUB_FUNC LIBTCCAPI
@@ -79,6 +88,30 @@ · 6 unmodified lines
7988 # define O_BINARY 0
8089 #endif
8190
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+
82115 #include "elf.h"
83116 #ifdef TCC_TARGET_X86_64
84117 # define ELFCLASSW ELFCLASS64
@@ -315,7 +348,7 @@ typedef union CValue { · 230 unmodified lines
315348 long long ll;
316349 unsigned long long ull;
317350 struct CString *cstr;
318− void *ptr;
351+ addr_t ptr_offset;
319352 int tab[LDOUBLE_SIZE/4];
320353 } CValue;
321354
@@ -938,37 +971,6 @@ enum tcc_token { · 616 unmodified lines
938971
939972 #define TOK_UIDENT TOK_DEFINE
940973
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 */
952−extern float strtof (const char *__nptr, char **__endptr);
953−extern 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−
972974 /* space exlcuding newline */
973975 static inline int is_space(int ch)
974976 {
@@ -1045,7 +1047,7 @@ PUB_FUNC char *tcc_strdup(const char *str); · 70 unmodified lines
10451047 #define strdup(s) use_tcc_strdup(s)
10461048 PUB_FUNC void tcc_memstats(void);
10471049 PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
1048−PUB_FUNC void tcc_error(const char *fmt, ...) __attribute__ ((noreturn));
1050+PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
10491051 PUB_FUNC void tcc_warning(const char *fmt, ...);
10501052
10511053 /* other utilities */
@@ -1143,7 +1145,7 @@ ST_FUNC void preprocess_init(TCCState *s1); · 91 unmodified lines
11431145 ST_FUNC void preprocess_new(void);
11441146 ST_FUNC int tcc_preprocess(TCCState *s1);
11451147 ST_FUNC void skip(int c);
1146−ST_FUNC void expect(const char *msg) __attribute__ ((noreturn));
1148+ST_FUNC NORETURN void expect(const char *msg);
11471149
11481150 /* ------------ tccgen.c ------------ */
11491151
tccgen.c+9−21
@@ -329,7 +329,6 @@ static void vsetc(CType *type, int r, CValue *vc) · 328 unmodified lines
329329 void vpush(CType *type)
330330 {
331331 CValue cval;
332− memset(&cval, 0, sizeof(CValue));
333332 vsetc(type, VT_CONST, &cval);
334333 }
335334
@@ -337,29 +336,23 @@ void vpush(CType *type) · 1 unmodified line
337336 ST_FUNC void vpushi(int v)
338337 {
339338 CValue cval;
340− memset(&cval, 0, sizeof(CValue));
341339 cval.i = v;
342340 vsetc(&int_type, VT_CONST, &cval);
343341 }
344342
345343 /* push a pointer sized constant */
346−static void vpushs(long long v)
344+static void vpushs(addr_t v)
347345 {
348346 CValue cval;
349− memset(&cval, 0, sizeof(CValue));
350− if (PTR_SIZE == 4)
351− cval.i = (int)v;
352− else
353− cval.ull = v;
347+ cval.ptr_offset = v;
354348 vsetc(&size_type, VT_CONST, &cval);
355349 }
356350
357351 /* push arbitrary 64bit constant */
358352 void vpush64(int ty, unsigned long long v)
359353 {
360− CType ctype;
361354 CValue cval;
362− memset(&cval, 0, sizeof(CValue));
355+ CType ctype;
363356 ctype.t = ty;
364357 ctype.ref = NULL;
365358 cval.ull = v;
@@ -376,9 +369,7 @@ static inline void vpushll(long long v) · 10 unmodified lines
376369 static inline void vpushsym(CType *type, Sym *sym)
377370 {
378371 CValue cval;
379− memset(&cval, 0, sizeof(CValue));
380−
381− cval.ull = 0;
372+ cval.ptr_offset = 0;
382373 vsetc(type, VT_CONST | VT_SYM, &cval);
383374 vtop->sym = sym;
384375 }
@@ -451,7 +442,6 @@ ST_FUNC void vpush_global_sym(CType *type, int v) · 66 unmodified lines
451442 ST_FUNC void vset(CType *type, int r, int v)
452443 {
453444 CValue cval;
454− memset(&cval, 0, sizeof(CValue));
455445
456446 cval.i = v;
457447 vsetc(type, r, &cval);
@@ -737,7 +727,6 @@ ST_FUNC int gv(int rc) · 279 unmodified lines
737727 unsigned long offset;
738728 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
739729 CValue check;
740− memset(&check, 0, sizeof(CValue));
741730 #endif
742731
743732 /* XXX: unify with initializers handling ? */
@@ -770,7 +759,7 @@ ST_FUNC int gv(int rc) · 26 unmodified lines
770759 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
771760 vtop->r |= VT_LVAL | VT_SYM;
772761 vtop->sym = sym;
773− vtop->c.ull = 0;
762+ vtop->c.ptr_offset = 0;
774763 }
775764 #ifdef CONFIG_TCC_BCHECK
776765 if (vtop->r & VT_MUSTBOUND)
@@ -1581,7 +1570,7 @@ static inline int is_null_pointer(SValue *p) · 804 unmodified lines
15811570 return 0;
15821571 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
15831572 ((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);
15851574 }
15861575
15871576 static inline int is_integer_btype(int bt)
@@ -3886,8 +3875,7 @@ ST_FUNC void unary(void) · 2298 unmodified lines
38863875 mk_pointer(&s->type);
38873876 s->type.t |= VT_STATIC;
38883877 }
3889− vset(&s->type, VT_CONST | VT_SYM, 0);
3890− vtop->sym = s;
3878+ vpushsym(&s->type, s);
38913879 next();
38923880 break;
38933881
@@ -3939,7 +3927,7 @@ ST_FUNC void unary(void) · 45 unmodified lines
39393927 /* if forward reference, we must point to s */
39403928 if (vtop->r & VT_SYM) {
39413929 vtop->sym = s;
3942− vtop->c.ull = 0;
3930+ vtop->c.ptr_offset = 0;
39433931 }
39443932 break;
39453933 }
@@ -5157,7 +5145,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c, · 1211 unmodified lines
51575145 if (vtop->r & VT_SYM) {
51585146 greloc(sec, vtop->sym, c, R_DATA_PTR);
51595147 }
5160− *(addr_t *)ptr |= (vtop->c.ull & bit_mask) << bit_pos;
5148+ *(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
51615149 break;
51625150 default:
51635151 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
974974 ST_FUNC void tok_str_add_tok(TokenString *s)
975975 {
976976 CValue cval;
977− memset(&cval, 0, sizeof(CValue));
978977
979978 /* save line number info */
980979 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
10381037 static int macro_is_equal(const int *a, const int *b)
10391038 {
10401039 char buf[STRING_MAX_SIZE + 1];
1041− int t;
10421040 CValue cv;
1043− memset(&cv, 0, sizeof(CValue));
1041+ int t;
10441042 while (*a && *b) {
10451043 TOK_GET(&t, &a, &cv);
10461044 pstrcpy(buf, sizeof buf, get_tok_str(t, &cv));
@@ -1199,7 +1197,6 @@ static void tok_print(int *str) · 152 unmodified lines
11991197 {
12001198 int t;
12011199 CValue cval;
1202− memset(&cval, 0, sizeof(CValue));
12031200
12041201 printf("<");
12051202 while (1) {
@@ -2566,10 +2563,9 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 1360 unmodified lines
25662563 int last_tok, t, spc;
25672564 const int *st;
25682565 Sym *s;
2566+ CValue cval;
25692567 TokenString str;
25702568 CString cstr;
2571− CValue cval;
2572− memset(&cval, 0, sizeof(CValue));
25732569
25742570 tok_str_new(&str);
25752571 last_tok = 0;
@@ -2671,10 +2667,9 @@ static int macro_subst_tok(TokenString *tok_str, · 95 unmodified lines
26712667 const int *p;
26722668 TokenString str;
26732669 char *cstrval;
2670+ CValue cval;
26742671 CString cstr;
26752672 char buf[32];
2676− CValue cval;
2677− memset(&cval, 0, sizeof(CValue));
26782673
26792674 /* if symbol is a macro, prepare substitution */
26802675 /* special macros */
@@ -2849,7 +2844,6 @@ static inline int *macro_twosharps(const int *macro_str) · 168 unmodified lines
28492844 /* we search the first '##' */
28502845 for(ptr = macro_str;;) {
28512846 CValue cval;
2852− memset(&cval, 0, sizeof(CValue));
28532847 TOK_GET(&t, &ptr, &cval);
28542848 if (t == TOK_TWOSHARPS)
28552849 break;
@@ -2880,7 +2874,6 @@ static inline int *macro_twosharps(const int *macro_str) · 24 unmodified lines
28802874 t = *++ptr;
28812875 if (t && t != TOK_TWOSHARPS) {
28822876 CValue cval;
2883− memset(&cval, 0, sizeof(CValue));
28842877 TOK_GET(&t, &ptr, &cval);
28852878 /* We concatenate the two tokens */
28862879 cstr_new(&cstr);
@@ -2922,10 +2915,9 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 35 unmodified lines
29222915 int *macro_str1;
29232916 const int *ptr;
29242917 int t, ret, spc;
2918+ CValue cval;
29252919 struct macro_level ml;
29262920 int force_blank;
2927− CValue cval;
2928− memset(&cval, 0, sizeof(CValue));
29292921
29302922 /* first scan for '##' operator handling */
29312923 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