Fix Fixes for PE x86_64 for fail in code
Applying 64bit relocs assumes that the CVal is initialized to zero for the whole 64bit. Consolidate this a bit, at the same time zeroing the .ull member more consistently when needed. Fixes segfault on x86_64-linux using global vars in tcctest.c.
This commit is contained in:
parent
80b36ab628
commit
9e11476e15
1 changed files with 20 additions and 27 deletions
45
tccgen.c
45
tccgen.c
|
|
@ -369,6 +369,16 @@ static inline void vpushll(long long v)
|
||||||
vpush64(VT_LLONG, v);
|
vpush64(VT_LLONG, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* push a symbol value of TYPE */
|
||||||
|
static inline void vpushsym(CType *type, Sym *sym)
|
||||||
|
{
|
||||||
|
CValue cval;
|
||||||
|
|
||||||
|
cval.ull = 0;
|
||||||
|
vsetc(type, VT_CONST | VT_SYM, &cval);
|
||||||
|
vtop->sym = sym;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a static symbol pointing to a section */
|
/* Return a static symbol pointing to a section */
|
||||||
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
|
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
|
||||||
{
|
{
|
||||||
|
|
@ -386,11 +396,7 @@ ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsign
|
||||||
/* push a reference to a section offset by adding a dummy symbol */
|
/* push a reference to a section offset by adding a dummy symbol */
|
||||||
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
|
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
|
||||||
{
|
{
|
||||||
CValue cval;
|
vpushsym(type, get_sym_ref(type, sec, offset, size));
|
||||||
|
|
||||||
cval.ul = 0;
|
|
||||||
vsetc(type, VT_CONST | VT_SYM, &cval);
|
|
||||||
vtop->sym = get_sym_ref(type, sec, offset, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define a new external reference to a symbol 'v' of type 'u' */
|
/* define a new external reference to a symbol 'v' of type 'u' */
|
||||||
|
|
@ -435,18 +441,12 @@ static Sym *external_sym(int v, CType *type, int r, char *asm_label)
|
||||||
/* push a reference to global symbol v */
|
/* push a reference to global symbol v */
|
||||||
ST_FUNC void vpush_global_sym(CType *type, int v)
|
ST_FUNC void vpush_global_sym(CType *type, int v)
|
||||||
{
|
{
|
||||||
Sym *sym;
|
vpushsym(type, external_global_sym(v, type, 0));
|
||||||
CValue cval;
|
|
||||||
|
|
||||||
sym = external_global_sym(v, type, 0);
|
|
||||||
cval.ul = 0;
|
|
||||||
vsetc(type, VT_CONST | VT_SYM, &cval);
|
|
||||||
vtop->sym = sym;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void vset(CType *type, int r, int v)
|
ST_FUNC void vset(CType *type, int r, int v)
|
||||||
{
|
{
|
||||||
CValue cval = {0};
|
CValue cval;
|
||||||
|
|
||||||
cval.i = v;
|
cval.i = v;
|
||||||
vsetc(type, r, &cval);
|
vsetc(type, r, &cval);
|
||||||
|
|
@ -764,7 +764,7 @@ ST_FUNC int gv(int rc)
|
||||||
sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
|
sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
|
||||||
vtop->r |= VT_LVAL | VT_SYM;
|
vtop->r |= VT_LVAL | VT_SYM;
|
||||||
vtop->sym = sym;
|
vtop->sym = sym;
|
||||||
vtop->c.ul = 0;
|
vtop->c.ull = 0;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (vtop->r & VT_MUSTBOUND)
|
if (vtop->r & VT_MUSTBOUND)
|
||||||
|
|
@ -1949,15 +1949,16 @@ static void gen_cast(CType *type)
|
||||||
vtop->c.ull = vtop->c.ll;
|
vtop->c.ull = vtop->c.ll;
|
||||||
else if (dbt == VT_BOOL)
|
else if (dbt == VT_BOOL)
|
||||||
vtop->c.i = (vtop->c.ll != 0);
|
vtop->c.i = (vtop->c.ll != 0);
|
||||||
|
#ifdef TCC_TARGET_X86_64
|
||||||
|
else if (dbt == VT_PTR)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
else if (dbt != VT_LLONG) {
|
else if (dbt != VT_LLONG) {
|
||||||
int s = 0;
|
int s = 0;
|
||||||
if ((dbt & VT_BTYPE) == VT_BYTE)
|
if ((dbt & VT_BTYPE) == VT_BYTE)
|
||||||
s = 24;
|
s = 24;
|
||||||
else if ((dbt & VT_BTYPE) == VT_SHORT)
|
else if ((dbt & VT_BTYPE) == VT_SHORT)
|
||||||
s = 16;
|
s = 16;
|
||||||
#ifdef TCC_TARGET_X86_64
|
|
||||||
if (!(dbt & (VT_PTR|VT_LLONG|VT_FUNC|VT_STRUCT)))
|
|
||||||
#endif
|
|
||||||
if(dbt & VT_UNSIGNED)
|
if(dbt & VT_UNSIGNED)
|
||||||
vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
|
vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
|
||||||
else
|
else
|
||||||
|
|
@ -3908,11 +3909,7 @@ ST_FUNC void unary(void)
|
||||||
/* if forward reference, we must point to s */
|
/* if forward reference, we must point to s */
|
||||||
if (vtop->r & VT_SYM) {
|
if (vtop->r & VT_SYM) {
|
||||||
vtop->sym = s;
|
vtop->sym = s;
|
||||||
#ifdef TCC_TARGET_X86_64
|
|
||||||
vtop->c.ull = 0;
|
vtop->c.ull = 0;
|
||||||
#else
|
|
||||||
vtop->c.ul = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -5617,13 +5614,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
esym->st_shndx = SHN_COMMON;
|
esym->st_shndx = SHN_COMMON;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CValue cval;
|
|
||||||
|
|
||||||
/* push global reference */
|
/* push global reference */
|
||||||
sym = get_sym_ref(type, sec, addr, size);
|
sym = get_sym_ref(type, sec, addr, size);
|
||||||
cval.ul = 0;
|
vpushsym(type, sym);
|
||||||
vsetc(type, VT_CONST | VT_SYM, &cval);
|
|
||||||
vtop->sym = sym;
|
|
||||||
}
|
}
|
||||||
/* patch symbol weakness */
|
/* patch symbol weakness */
|
||||||
if (type->t & VT_WEAK)
|
if (type->t & VT_WEAK)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue