Accept symbols in initializers also on 64 bit

Those should use long or long long type, and generate a 64bit reloc.
master
Michael Matz 2016-07-11 16:26:36 +02:00
parent 920474115c
commit 10c3514889
2 changed files with 20 additions and 3 deletions

View File

@ -5777,7 +5777,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
/* XXX: make code faster ? */
if (!(type->t & VT_BITFIELD)) {
bit_pos = 0;
bit_size = 32;
bit_size = PTR_SIZE * 8;
bit_mask = -1LL;
} else {
bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
@ -5789,8 +5789,14 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
bt == VT_SHORT ||
bt == VT_DOUBLE ||
bt == VT_LDOUBLE ||
bt == VT_LLONG ||
(bt == VT_INT && bit_size != 32)))
#if PTR_SIZE == 8
(bt == VT_LLONG && bit_size != 64) ||
bt == VT_INT
#else
bt == VT_LLONG ||
(bt == VT_INT && bit_size != 32)
#endif
))
tcc_error("initializer element is not computable at load time");
switch(bt) {
/* XXX: when cross-compiling we assume that each type has the
@ -5815,9 +5821,13 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
else
tcc_error("can't cross compile long double constants");
break;
#if PTR_SIZE != 8
case VT_LLONG:
*(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
break;
#else
case VT_LLONG:
#endif
case VT_PTR: {
addr_t val = (vtop->c.i & bit_mask) << bit_pos;
#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)

View File

@ -2230,10 +2230,17 @@ int reltab[3] = { 1, 2, 3 };
int *rel1 = &reltab[1];
int *rel2 = &reltab[2];
void getmyaddress(void)
{
printf("in getmyaddress\n");
}
unsigned long theaddress = (unsigned long)getmyaddress;
void relocation_test(void)
{
void (*fptr)(void) = (void (*)(void))theaddress;
printf("*rel1=%d\n", *rel1);
printf("*rel2=%d\n", *rel2);
fptr();
}
void old_style_f(a,b,c)