Clean up lots of rogue tabs.
Still some more tabs to be taken care of. arm-gen.c and tcccoff.c have so many style issues that I'm just going to throw clang-format at them.
This commit is contained in:
parent
41031221c8
commit
d6b64e2574
10 changed files with 426 additions and 427 deletions
38
c67-gen.c
38
c67-gen.c
|
@ -30,13 +30,13 @@ typedef int RegArgs;
|
||||||
/* a register can belong to several classes. The classes must be
|
/* a register can belong to several classes. The classes must be
|
||||||
sorted from more general to more precise (see gv2() code which does
|
sorted from more general to more precise (see gv2() code which does
|
||||||
assumptions on it). */
|
assumptions on it). */
|
||||||
#define RC_INT 0x0001 /* generic integer register */
|
#define RC_INT 0x0001 /* generic integer register */
|
||||||
#define RC_FLOAT 0x0002 /* generic float register */
|
#define RC_FLOAT 0x0002 /* generic float register */
|
||||||
#define RC_EAX 0x0004
|
#define RC_EAX 0x0004
|
||||||
#define RC_ST0 0x0008
|
#define RC_ST0 0x0008
|
||||||
#define RC_ECX 0x0010
|
#define RC_ECX 0x0010
|
||||||
#define RC_EDX 0x0020
|
#define RC_EDX 0x0020
|
||||||
#define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */
|
#define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */
|
||||||
#define RC_C67_A4 0x00000100
|
#define RC_C67_A4 0x00000100
|
||||||
#define RC_C67_A5 0x00000200
|
#define RC_C67_A5 0x00000200
|
||||||
#define RC_C67_B4 0x00000400
|
#define RC_C67_B4 0x00000400
|
||||||
|
@ -204,7 +204,7 @@ void C67_g(int c)
|
||||||
#endif
|
#endif
|
||||||
ind1 = ind + 4;
|
ind1 = ind + 4;
|
||||||
if (ind1 > (int) cur_text_section->data_allocated)
|
if (ind1 > (int) cur_text_section->data_allocated)
|
||||||
section_realloc(cur_text_section, ind1);
|
section_realloc(cur_text_section, ind1);
|
||||||
cur_text_section->data[ind] = c & 0xff;
|
cur_text_section->data[ind] = c & 0xff;
|
||||||
cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
|
cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
|
||||||
cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
|
cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
|
||||||
|
@ -218,26 +218,26 @@ void gsym_addr(int t, int a)
|
||||||
{
|
{
|
||||||
int n, *ptr;
|
int n, *ptr;
|
||||||
while (t) {
|
while (t) {
|
||||||
ptr = (int *) (cur_text_section->data + t);
|
ptr = (int *) (cur_text_section->data + t);
|
||||||
{
|
{
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
|
||||||
// extract 32 bit address from MVKH/MVKL
|
// extract 32 bit address from MVKH/MVKL
|
||||||
n = ((*ptr >> 7) & 0xffff);
|
n = ((*ptr >> 7) & 0xffff);
|
||||||
n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
|
n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
|
||||||
|
|
||||||
// define a label that will be relocated
|
// define a label that will be relocated
|
||||||
|
|
||||||
sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
|
sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
|
||||||
greloc(cur_text_section, sym, t, R_C60LO16);
|
greloc(cur_text_section, sym, t, R_C60LO16);
|
||||||
greloc(cur_text_section, sym, t + 4, R_C60HI16);
|
greloc(cur_text_section, sym, t + 4, R_C60HI16);
|
||||||
|
|
||||||
// clear out where the pointer was
|
// clear out where the pointer was
|
||||||
|
|
||||||
*ptr &= ~(0xffff << 7);
|
*ptr &= ~(0xffff << 7);
|
||||||
*(ptr + 1) &= ~(0xffff << 7);
|
*(ptr + 1) &= ~(0xffff << 7);
|
||||||
}
|
}
|
||||||
t = n;
|
t = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
coff.h
2
coff.h
|
@ -370,7 +370,7 @@ struct syment
|
||||||
#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
|
#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
|
||||||
#define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
|
#define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
/* AUXILIARY SYMBOL ENTRY */
|
/* AUXILIARY SYMBOL ENTRY */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
18
libtcc.c
18
libtcc.c
|
@ -672,7 +672,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (! (sym->type.t & VT_STATIC))
|
if (! (sym->type.t & VT_STATIC))
|
||||||
other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
|
other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
|
||||||
#endif
|
#endif
|
||||||
if (tcc_state->leading_underscore && can_add_underscore) {
|
if (tcc_state->leading_underscore && can_add_underscore) {
|
||||||
buf1[0] = '_';
|
buf1[0] = '_';
|
||||||
|
@ -2101,11 +2101,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||||
s->static_link = 1;
|
s->static_link = 1;
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_std:
|
case TCC_OPTION_std:
|
||||||
/* silently ignore, a current purpose:
|
/* silently ignore, a current purpose:
|
||||||
allow to use a tcc as a reference compiler for "make test" */
|
allow to use a tcc as a reference compiler for "make test" */
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_shared:
|
case TCC_OPTION_shared:
|
||||||
if (s->output_type)
|
if (s->output_type)
|
||||||
tcc_warning("-shared: some compiler action already specified (%d)", s->output_type);
|
tcc_warning("-shared: some compiler action already specified (%d)", s->output_type);
|
||||||
s->output_type = TCC_OUTPUT_DLL;
|
s->output_type = TCC_OUTPUT_DLL;
|
||||||
break;
|
break;
|
||||||
|
@ -2124,7 +2124,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_r:
|
case TCC_OPTION_r:
|
||||||
/* generate a .o merging several output files */
|
/* generate a .o merging several output files */
|
||||||
if (s->output_type)
|
if (s->output_type)
|
||||||
tcc_warning("-r: some compiler action already specified (%d)", s->output_type);
|
tcc_warning("-r: some compiler action already specified (%d)", s->output_type);
|
||||||
s->option_r = 1;
|
s->option_r = 1;
|
||||||
s->output_type = TCC_OUTPUT_OBJ;
|
s->output_type = TCC_OUTPUT_OBJ;
|
||||||
|
@ -2163,7 +2163,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||||
s->print_search_dirs = 1;
|
s->print_search_dirs = 1;
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_run:
|
case TCC_OPTION_run:
|
||||||
if (s->output_type)
|
if (s->output_type)
|
||||||
tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
|
tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
|
||||||
s->output_type = TCC_OUTPUT_MEMORY;
|
s->output_type = TCC_OUTPUT_MEMORY;
|
||||||
tcc_set_options(s, optarg);
|
tcc_set_options(s, optarg);
|
||||||
|
@ -2194,7 +2194,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||||
cstr_ccat(&linker_arg, '\0');
|
cstr_ccat(&linker_arg, '\0');
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_E:
|
case TCC_OPTION_E:
|
||||||
if (s->output_type)
|
if (s->output_type)
|
||||||
tcc_warning("-E: some compiler action already specified (%d)", s->output_type);
|
tcc_warning("-E: some compiler action already specified (%d)", s->output_type);
|
||||||
s->output_type = TCC_OUTPUT_PREPROCESS;
|
s->output_type = TCC_OUTPUT_PREPROCESS;
|
||||||
break;
|
break;
|
||||||
|
@ -2251,13 +2251,13 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->output_type == 0)
|
if (s->output_type == 0)
|
||||||
s->output_type = TCC_OUTPUT_EXE;
|
s->output_type = TCC_OUTPUT_EXE;
|
||||||
|
|
||||||
if (pthread && s->output_type != TCC_OUTPUT_OBJ)
|
if (pthread && s->output_type != TCC_OUTPUT_OBJ)
|
||||||
tcc_set_options(s, "-lpthread");
|
tcc_set_options(s, "-lpthread");
|
||||||
|
|
||||||
if (s->output_type == TCC_OUTPUT_EXE)
|
if (s->output_type == TCC_OUTPUT_EXE)
|
||||||
tcc_set_linker(s, (const char *)linker_arg.data);
|
tcc_set_linker(s, (const char *)linker_arg.data);
|
||||||
cstr_free(&linker_arg);
|
cstr_free(&linker_arg);
|
||||||
|
|
||||||
return optind;
|
return optind;
|
||||||
|
|
34
tccasm.c
34
tccasm.c
|
@ -92,10 +92,10 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
|
||||||
break;
|
break;
|
||||||
case TOK_CCHAR:
|
case TOK_CCHAR:
|
||||||
case TOK_LCHAR:
|
case TOK_LCHAR:
|
||||||
pe->v = tokc.i;
|
pe->v = tokc.i;
|
||||||
pe->sym = NULL;
|
pe->sym = NULL;
|
||||||
next();
|
next();
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
next();
|
next();
|
||||||
asm_expr(s1, pe);
|
asm_expr(s1, pe);
|
||||||
|
@ -493,7 +493,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
case TOK_ASM_weak:
|
case TOK_ASM_weak:
|
||||||
case TOK_ASM_hidden:
|
case TOK_ASM_hidden:
|
||||||
tok1 = tok;
|
tok1 = tok;
|
||||||
do {
|
do {
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
@ -502,15 +502,15 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
sym = label_push(&s1->asm_labels, tok, 0);
|
sym = label_push(&s1->asm_labels, tok, 0);
|
||||||
sym->type.t = VT_VOID;
|
sym->type.t = VT_VOID;
|
||||||
}
|
}
|
||||||
if (tok1 != TOK_ASM_hidden)
|
if (tok1 != TOK_ASM_hidden)
|
||||||
sym->type.t &= ~VT_STATIC;
|
sym->type.t &= ~VT_STATIC;
|
||||||
if (tok1 == TOK_ASM_weak)
|
if (tok1 == TOK_ASM_weak)
|
||||||
sym->type.t |= VT_WEAK;
|
sym->type.t |= VT_WEAK;
|
||||||
else if (tok1 == TOK_ASM_hidden)
|
else if (tok1 == TOK_ASM_hidden)
|
||||||
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
|
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
|
||||||
next();
|
next();
|
||||||
} while (tok == ',');
|
} while (tok == ',');
|
||||||
break;
|
break;
|
||||||
case TOK_ASM_string:
|
case TOK_ASM_string:
|
||||||
case TOK_ASM_ascii:
|
case TOK_ASM_ascii:
|
||||||
case TOK_ASM_asciz:
|
case TOK_ASM_asciz:
|
||||||
|
@ -536,24 +536,24 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_ASM_text:
|
case TOK_ASM_text:
|
||||||
case TOK_ASM_data:
|
case TOK_ASM_data:
|
||||||
case TOK_ASM_bss:
|
case TOK_ASM_bss:
|
||||||
{
|
{
|
||||||
char sname[64];
|
char sname[64];
|
||||||
tok1 = tok;
|
tok1 = tok;
|
||||||
n = 0;
|
n = 0;
|
||||||
next();
|
next();
|
||||||
if (tok != ';' && tok != TOK_LINEFEED) {
|
if (tok != ';' && tok != TOK_LINEFEED) {
|
||||||
n = asm_int_expr(s1);
|
n = asm_int_expr(s1);
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
|
sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
|
||||||
use_section(s1, sname);
|
use_section(s1, sname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_ASM_file:
|
case TOK_ASM_file:
|
||||||
{
|
{
|
||||||
char filename[512];
|
char filename[512];
|
||||||
|
|
278
tccelf.c
278
tccelf.c
|
@ -451,7 +451,7 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
|
||||||
if (addr) {
|
if (addr) {
|
||||||
sym->st_value = (addr_t)addr;
|
sym->st_value = (addr_t)addr;
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
|
printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
|
||||||
#endif
|
#endif
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
@ -580,10 +580,10 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||||
{
|
{
|
||||||
int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
|
int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
|
||||||
x = (*(int *) ptr) & 0xffffff;
|
x = (*(int *) ptr) & 0xffffff;
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
if (sym->st_shndx == SHN_UNDEF)
|
||||||
val = s1->plt->sh_addr;
|
val = s1->plt->sh_addr;
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
|
printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
|
||||||
#endif
|
#endif
|
||||||
(*(int *)ptr) &= 0xff000000;
|
(*(int *)ptr) &= 0xff000000;
|
||||||
if (x & 0x800000)
|
if (x & 0x800000)
|
||||||
|
@ -595,8 +595,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||||
is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
|
is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
|
||||||
x += val - addr;
|
x += val - addr;
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf (" newx=0x%x name=%s\n", x,
|
printf (" newx=0x%x name=%s\n", x,
|
||||||
(char *) symtab_section->link->data + sym->st_name);
|
(char *) symtab_section->link->data + sym->st_name);
|
||||||
#endif
|
#endif
|
||||||
h = x & 2;
|
h = x & 2;
|
||||||
th_ko = (x & 3) && (!blx_avail || !is_call);
|
th_ko = (x & 3) && (!blx_avail || !is_call);
|
||||||
|
@ -797,21 +797,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||||
break;
|
break;
|
||||||
case R_AARCH64_JUMP26:
|
case R_AARCH64_JUMP26:
|
||||||
case R_AARCH64_CALL26:
|
case R_AARCH64_CALL26:
|
||||||
/* This check must match the one in build_got_entries, testing
|
/* This check must match the one in build_got_entries, testing
|
||||||
if we really need a PLT slot. */
|
if we really need a PLT slot. */
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
if (sym->st_shndx == SHN_UNDEF)
|
||||||
/* We've put the PLT slot offset into r_addend when generating
|
/* We've put the PLT slot offset into r_addend when generating
|
||||||
it, and that's what we must use as relocation value (adjusted
|
it, and that's what we must use as relocation value (adjusted
|
||||||
by section offset of course). */
|
by section offset of course). */
|
||||||
val = s1->plt->sh_addr + rel->r_addend;
|
val = s1->plt->sh_addr + rel->r_addend;
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
||||||
(char *) symtab_section->link->data + sym->st_name);
|
(char *) symtab_section->link->data + sym->st_name);
|
||||||
#endif
|
#endif
|
||||||
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
|
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
|
||||||
{
|
{
|
||||||
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
|
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
|
||||||
}
|
}
|
||||||
*(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |
|
*(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |
|
||||||
((val - addr) >> 2 & 0x3ffffff);
|
((val - addr) >> 2 & 0x3ffffff);
|
||||||
break;
|
break;
|
||||||
|
@ -836,9 +836,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||||
case R_AARCH64_JUMP_SLOT:
|
case R_AARCH64_JUMP_SLOT:
|
||||||
/* They don't need addend */
|
/* They don't need addend */
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
|
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
|
||||||
val - rel->r_addend,
|
val - rel->r_addend,
|
||||||
(char *) symtab_section->link->data + sym->st_name);
|
(char *) symtab_section->link->data + sym->st_name);
|
||||||
#endif
|
#endif
|
||||||
*(addr_t *)ptr = val - rel->r_addend;
|
*(addr_t *)ptr = val - rel->r_addend;
|
||||||
break;
|
break;
|
||||||
|
@ -879,12 +879,12 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||||
qrel->r_offset = rel->r_offset;
|
qrel->r_offset = rel->r_offset;
|
||||||
if (esym_index) {
|
if (esym_index) {
|
||||||
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
|
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
|
||||||
qrel->r_addend = rel->r_addend;
|
qrel->r_addend = rel->r_addend;
|
||||||
qrel++;
|
qrel++;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
|
qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
|
||||||
qrel->r_addend = *(long long *)ptr + val;
|
qrel->r_addend = *(long long *)ptr + val;
|
||||||
qrel++;
|
qrel++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,14 +917,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||||
goto plt32pc32;
|
goto plt32pc32;
|
||||||
|
|
||||||
case R_X86_64_PLT32:
|
case R_X86_64_PLT32:
|
||||||
/* We've put the PLT slot offset into r_addend when generating
|
/* We've put the PLT slot offset into r_addend when generating
|
||||||
it, and that's what we must use as relocation value (adjusted
|
it, and that's what we must use as relocation value (adjusted
|
||||||
by section offset of course). */
|
by section offset of course). */
|
||||||
val = s1->plt->sh_addr + rel->r_addend;
|
val = s1->plt->sh_addr + rel->r_addend;
|
||||||
/* fallthrough. */
|
/* fallthrough. */
|
||||||
|
|
||||||
plt32pc32:
|
plt32pc32:
|
||||||
{
|
{
|
||||||
long long diff;
|
long long diff;
|
||||||
diff = (long long)val - addr;
|
diff = (long long)val - addr;
|
||||||
if (diff < -2147483648LL || diff > 2147483647LL) {
|
if (diff < -2147483648LL || diff > 2147483647LL) {
|
||||||
|
@ -1080,8 +1080,8 @@ static void build_got(TCCState *s1)
|
||||||
and 'info' can be modifed if more precise info comes from the DLL.
|
and 'info' can be modifed if more precise info comes from the DLL.
|
||||||
Returns offset of GOT or PLT slot. */
|
Returns offset of GOT or PLT slot. */
|
||||||
static unsigned long put_got_entry(TCCState *s1,
|
static unsigned long put_got_entry(TCCState *s1,
|
||||||
int reloc_type, unsigned long size, int info,
|
int reloc_type, unsigned long size, int info,
|
||||||
int sym_index)
|
int sym_index)
|
||||||
{
|
{
|
||||||
int index, need_plt_entry;
|
int index, need_plt_entry;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -1107,18 +1107,18 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (need_plt_entry && !s1->plt) {
|
if (need_plt_entry && !s1->plt) {
|
||||||
/* add PLT */
|
/* add PLT */
|
||||||
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
|
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
|
||||||
SHF_ALLOC | SHF_EXECINSTR);
|
SHF_ALLOC | SHF_EXECINSTR);
|
||||||
s1->plt->sh_entsize = 4;
|
s1->plt->sh_entsize = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a got/plt entry already exists for that symbol, no need to add one */
|
/* If a got/plt entry already exists for that symbol, no need to add one */
|
||||||
if (sym_index < s1->nb_sym_attrs) {
|
if (sym_index < s1->nb_sym_attrs) {
|
||||||
if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
|
if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
|
||||||
return s1->sym_attrs[sym_index].plt_offset;
|
return s1->sym_attrs[sym_index].plt_offset;
|
||||||
else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
|
else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
|
||||||
return s1->sym_attrs[sym_index].got_offset;
|
return s1->sym_attrs[sym_index].got_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
symattr = alloc_sym_attr(s1, sym_index);
|
symattr = alloc_sym_attr(s1, sym_index);
|
||||||
|
@ -1135,7 +1135,7 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
Section *plt;
|
Section *plt;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
int modrm;
|
int modrm;
|
||||||
unsigned long relofs;
|
unsigned long relofs;
|
||||||
|
|
||||||
#if defined(TCC_OUTPUT_DLL_WITH_PLT)
|
#if defined(TCC_OUTPUT_DLL_WITH_PLT)
|
||||||
modrm = 0x25;
|
modrm = 0x25;
|
||||||
|
@ -1160,10 +1160,10 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
put32(p + 8, PTR_SIZE * 2);
|
put32(p + 8, PTR_SIZE * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The PLT slot refers to the relocation entry it needs
|
/* The PLT slot refers to the relocation entry it needs
|
||||||
via offset. The reloc entry is created below, so its
|
via offset. The reloc entry is created below, so its
|
||||||
offset is the current data_offset. */
|
offset is the current data_offset. */
|
||||||
relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
|
relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
|
||||||
symattr->plt_offset = plt->data_offset;
|
symattr->plt_offset = plt->data_offset;
|
||||||
p = section_ptr_add(plt, 16);
|
p = section_ptr_add(plt, 16);
|
||||||
p[0] = 0xff; /* jmp *(got + x) */
|
p[0] = 0xff; /* jmp *(got + x) */
|
||||||
|
@ -1171,19 +1171,19 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
put32(p + 2, s1->got->data_offset);
|
put32(p + 2, s1->got->data_offset);
|
||||||
p[6] = 0x68; /* push $xxx */
|
p[6] = 0x68; /* push $xxx */
|
||||||
#ifdef TCC_TARGET_X86_64
|
#ifdef TCC_TARGET_X86_64
|
||||||
/* On x86-64, the relocation is referred to by _index_. */
|
/* On x86-64, the relocation is referred to by _index_. */
|
||||||
put32(p + 7, relofs / sizeof (ElfW_Rel));
|
put32(p + 7, relofs / sizeof (ElfW_Rel));
|
||||||
#else
|
#else
|
||||||
put32(p + 7, relofs);
|
put32(p + 7, relofs);
|
||||||
#endif
|
#endif
|
||||||
p[11] = 0xe9; /* jmp plt_start */
|
p[11] = 0xe9; /* jmp plt_start */
|
||||||
put32(p + 12, -(plt->data_offset));
|
put32(p + 12, -(plt->data_offset));
|
||||||
|
|
||||||
/* If this was an UNDEF symbol set the offset in the
|
/* If this was an UNDEF symbol set the offset in the
|
||||||
dynsymtab to the PLT slot, so that PC32 relocs to it
|
dynsymtab to the PLT slot, so that PC32 relocs to it
|
||||||
can be resolved. */
|
can be resolved. */
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
if (sym->st_shndx == SHN_UNDEF)
|
||||||
offset = plt->data_offset - 16;
|
offset = plt->data_offset - 16;
|
||||||
}
|
}
|
||||||
#elif defined(TCC_TARGET_ARM)
|
#elif defined(TCC_TARGET_ARM)
|
||||||
if (need_plt_entry) {
|
if (need_plt_entry) {
|
||||||
|
@ -1220,7 +1220,7 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
|
|
||||||
/* the symbol is modified so that it will be relocated to
|
/* the symbol is modified so that it will be relocated to
|
||||||
the PLT */
|
the PLT */
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
if (sym->st_shndx == SHN_UNDEF)
|
||||||
offset = plt->data_offset - 16;
|
offset = plt->data_offset - 16;
|
||||||
}
|
}
|
||||||
#elif defined(TCC_TARGET_ARM64)
|
#elif defined(TCC_TARGET_ARM64)
|
||||||
|
@ -1250,19 +1250,19 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
#error unsupported CPU
|
#error unsupported CPU
|
||||||
#endif
|
#endif
|
||||||
if (s1->dynsym) {
|
if (s1->dynsym) {
|
||||||
/* XXX This might generate multiple syms for name. */
|
/* XXX This might generate multiple syms for name. */
|
||||||
index = put_elf_sym(s1->dynsym, offset,
|
index = put_elf_sym(s1->dynsym, offset,
|
||||||
size, info, 0, sym->st_shndx, name);
|
size, info, 0, sym->st_shndx, name);
|
||||||
/* Create the relocation (it's against the GOT for PLT
|
/* Create the relocation (it's against the GOT for PLT
|
||||||
and GOT relocs). */
|
and GOT relocs). */
|
||||||
put_elf_reloc(s1->dynsym, s1->got,
|
put_elf_reloc(s1->dynsym, s1->got,
|
||||||
s1->got->data_offset,
|
s1->got->data_offset,
|
||||||
reloc_type, index);
|
reloc_type, index);
|
||||||
} else {
|
} else {
|
||||||
/* Without .dynsym (i.e. static link or memory output) we
|
/* Without .dynsym (i.e. static link or memory output) we
|
||||||
still need relocs against the generated got, so as to fill
|
still need relocs against the generated got, so as to fill
|
||||||
the entries with the symbol values (determined later). */
|
the entries with the symbol values (determined later). */
|
||||||
put_elf_reloc(symtab_section, s1->got,
|
put_elf_reloc(symtab_section, s1->got,
|
||||||
s1->got->data_offset,
|
s1->got->data_offset,
|
||||||
reloc_type, sym_index);
|
reloc_type, sym_index);
|
||||||
}
|
}
|
||||||
|
@ -1324,8 +1324,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||||
build_got(s1);
|
build_got(s1);
|
||||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||||
if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
|
if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
|
||||||
&& sym->st_shndx == SHN_UNDEF) {
|
&& sym->st_shndx == SHN_UNDEF) {
|
||||||
unsigned long ofs;
|
unsigned long ofs;
|
||||||
/* look at the symbol got offset. If none, then add one */
|
/* look at the symbol got offset. If none, then add one */
|
||||||
if (type == R_ARM_GOT32)
|
if (type == R_ARM_GOT32)
|
||||||
|
@ -1333,27 +1333,27 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||||
else
|
else
|
||||||
reloc_type = R_ARM_JUMP_SLOT;
|
reloc_type = R_ARM_JUMP_SLOT;
|
||||||
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
||||||
sym->st_info, sym_index);
|
sym->st_info, sym_index);
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
|
printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
|
||||||
(char *) symtab_section->link->data + sym->st_name,
|
(char *) symtab_section->link->data + sym->st_name,
|
||||||
type, sym->st_shndx, ofs);
|
type, sym->st_shndx, ofs);
|
||||||
#endif
|
#endif
|
||||||
if (type != R_ARM_GOT32) {
|
if (type != R_ARM_GOT32) {
|
||||||
addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
|
addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
|
||||||
+ rel->r_offset);
|
+ rel->r_offset);
|
||||||
/* x must be signed! */
|
/* x must be signed! */
|
||||||
int x = *ptr & 0xffffff;
|
int x = *ptr & 0xffffff;
|
||||||
x = (x << 8) >> 8;
|
x = (x << 8) >> 8;
|
||||||
x <<= 2;
|
x <<= 2;
|
||||||
x += ofs;
|
x += ofs;
|
||||||
x >>= 2;
|
x >>= 2;
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
|
printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
|
||||||
(*ptr & 0xff000000) | x, x);
|
(*ptr & 0xff000000) | x, x);
|
||||||
#endif
|
#endif
|
||||||
*ptr = (*ptr & 0xff000000) | x;
|
*ptr = (*ptr & 0xff000000) | x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_ARM_THM_JUMP24:
|
case R_ARM_THM_JUMP24:
|
||||||
|
@ -1397,22 +1397,22 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||||
sym_index);
|
sym_index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_AARCH64_JUMP26:
|
case R_AARCH64_JUMP26:
|
||||||
case R_AARCH64_CALL26:
|
case R_AARCH64_CALL26:
|
||||||
if (!s1->got)
|
if (!s1->got)
|
||||||
build_got(s1);
|
build_got(s1);
|
||||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||||
if (sym->st_shndx == SHN_UNDEF) {
|
if (sym->st_shndx == SHN_UNDEF) {
|
||||||
unsigned long ofs;
|
unsigned long ofs;
|
||||||
reloc_type = R_AARCH64_JUMP_SLOT;
|
reloc_type = R_AARCH64_JUMP_SLOT;
|
||||||
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
||||||
sym->st_info, sym_index);
|
sym->st_info, sym_index);
|
||||||
/* We store the place of the generated PLT slot
|
/* We store the place of the generated PLT slot
|
||||||
in our addend. */
|
in our addend. */
|
||||||
rel->r_addend += ofs;
|
rel->r_addend += ofs;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#elif defined(TCC_TARGET_C67)
|
#elif defined(TCC_TARGET_C67)
|
||||||
case R_C60_GOT32:
|
case R_C60_GOT32:
|
||||||
case R_C60_GOTOFF:
|
case R_C60_GOTOFF:
|
||||||
|
@ -1439,29 +1439,29 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||||
case R_X86_64_PLT32:
|
case R_X86_64_PLT32:
|
||||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||||
if (type == R_X86_64_PLT32 &&
|
if (type == R_X86_64_PLT32 &&
|
||||||
ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
|
ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
|
||||||
{
|
{
|
||||||
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
|
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s1->got)
|
if (!s1->got)
|
||||||
build_got(s1);
|
build_got(s1);
|
||||||
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
|
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
|
||||||
type == R_X86_64_PLT32) {
|
type == R_X86_64_PLT32) {
|
||||||
unsigned long ofs;
|
unsigned long ofs;
|
||||||
/* look at the symbol got offset. If none, then add one */
|
/* look at the symbol got offset. If none, then add one */
|
||||||
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
|
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
|
||||||
reloc_type = R_X86_64_GLOB_DAT;
|
reloc_type = R_X86_64_GLOB_DAT;
|
||||||
else
|
else
|
||||||
reloc_type = R_X86_64_JUMP_SLOT;
|
reloc_type = R_X86_64_JUMP_SLOT;
|
||||||
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
||||||
sym->st_info, sym_index);
|
sym->st_info, sym_index);
|
||||||
if (type == R_X86_64_PLT32)
|
if (type == R_X86_64_PLT32)
|
||||||
/* We store the place of the generated PLT slot
|
/* We store the place of the generated PLT slot
|
||||||
in our addend. */
|
in our addend. */
|
||||||
rel->r_addend += ofs;
|
rel->r_addend += ofs;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
|
@ -1546,21 +1546,21 @@ static int tcc_add_support(TCCState *s1, const char *filename)
|
||||||
snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path,
|
snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path,
|
||||||
/* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */
|
/* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */
|
||||||
#ifdef TCC_TARGET_I386
|
#ifdef TCC_TARGET_I386
|
||||||
"i386"
|
"i386"
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_X86_64
|
#ifdef TCC_TARGET_X86_64
|
||||||
"x86-64"
|
"x86-64"
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_ARM
|
#ifdef TCC_TARGET_ARM
|
||||||
"arm"
|
"arm"
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_ARM64
|
#ifdef TCC_TARGET_ARM64
|
||||||
"arm64"
|
"arm64"
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_C67
|
#ifdef TCC_TARGET_C67
|
||||||
"C67"
|
"C67"
|
||||||
#endif
|
#endif
|
||||||
,filename);
|
,filename);
|
||||||
|
|
||||||
return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY);
|
return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY);
|
||||||
}
|
}
|
||||||
|
@ -1587,17 +1587,17 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1)
|
||||||
when __bound_ptr_add, __bound_new_region,
|
when __bound_ptr_add, __bound_new_region,
|
||||||
__bound_delete_region called */
|
__bound_delete_region called */
|
||||||
|
|
||||||
int sym_index = find_elf_sym(symtab_section, "__bound_init");
|
int sym_index = find_elf_sym(symtab_section, "__bound_init");
|
||||||
if (sym_index) {
|
if (sym_index) {
|
||||||
Section *init_section = find_section(s1, ".init");
|
Section *init_section = find_section(s1, ".init");
|
||||||
unsigned char *pinit = section_ptr_add(init_section, 5);
|
unsigned char *pinit = section_ptr_add(init_section, 5);
|
||||||
pinit[0] = 0xe8;
|
pinit[0] = 0xe8;
|
||||||
put32(pinit + 1, -4);
|
put32(pinit + 1, -4);
|
||||||
put_elf_reloc(symtab_section, init_section,
|
put_elf_reloc(symtab_section, init_section,
|
||||||
init_section->data_offset - 4, R_386_PC32, sym_index);
|
init_section->data_offset - 4, R_386_PC32, sym_index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tcc_warning("__bound_init not defined");
|
tcc_warning("__bound_init not defined");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1905,11 +1905,11 @@ static void export_global_syms(TCCState *s1)
|
||||||
s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
|
s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
|
||||||
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||||
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
|
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
|
||||||
name = (char *) symtab_section->link->data + sym->st_name;
|
name = (char *) symtab_section->link->data + sym->st_name;
|
||||||
dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
|
dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
|
||||||
sym->st_info, 0, sym->st_shndx, name);
|
sym->st_info, 0, sym->st_shndx, name);
|
||||||
index = sym - (ElfW(Sym) *) symtab_section->data;
|
index = sym - (ElfW(Sym) *) symtab_section->data;
|
||||||
s1->symtab_to_dynsym[index] = dynindex;
|
s1->symtab_to_dynsym[index] = dynindex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2179,15 +2179,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
file_offset += s->sh_size;
|
file_offset += s->sh_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
/* Make the first PT_LOAD segment include the program
|
/* Make the first PT_LOAD segment include the program
|
||||||
headers itself (and the ELF header as well), it'll
|
headers itself (and the ELF header as well), it'll
|
||||||
come out with same memory use but will make various
|
come out with same memory use but will make various
|
||||||
tools like binutils strip work better. */
|
tools like binutils strip work better. */
|
||||||
ph->p_offset &= ~(ph->p_align - 1);
|
ph->p_offset &= ~(ph->p_align - 1);
|
||||||
ph->p_vaddr &= ~(ph->p_align - 1);
|
ph->p_vaddr &= ~(ph->p_align - 1);
|
||||||
ph->p_paddr &= ~(ph->p_align - 1);
|
ph->p_paddr &= ~(ph->p_align - 1);
|
||||||
}
|
}
|
||||||
ph->p_filesz = file_offset - ph->p_offset;
|
ph->p_filesz = file_offset - ph->p_offset;
|
||||||
ph->p_memsz = addr - ph->p_vaddr;
|
ph->p_memsz = addr - ph->p_vaddr;
|
||||||
ph++;
|
ph++;
|
||||||
|
@ -2662,10 +2662,10 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
|
for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
|
||||||
if (sym->st_shndx == SHN_UNDEF) {
|
if (sym->st_shndx == SHN_UNDEF) {
|
||||||
/* relocate to PLT if symbol corresponds to a PLT entry,
|
/* relocate to PLT if symbol corresponds to a PLT entry,
|
||||||
but not if it's a weak symbol */
|
but not if it's a weak symbol */
|
||||||
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
||||||
sym->st_value = 0;
|
sym->st_value = 0;
|
||||||
else if (sym->st_value)
|
else if (sym->st_value)
|
||||||
sym->st_value += s1->plt->sh_addr;
|
sym->st_value += s1->plt->sh_addr;
|
||||||
} else if (sym->st_shndx < SHN_LORESERVE) {
|
} else if (sym->st_shndx < SHN_LORESERVE) {
|
||||||
/* do symbol relocation */
|
/* do symbol relocation */
|
||||||
|
@ -2690,14 +2690,14 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
/* Create the ELF file with name 'filename' */
|
/* Create the ELF file with name 'filename' */
|
||||||
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
|
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
|
||||||
if (s1->do_strip) {
|
if (s1->do_strip) {
|
||||||
int rc;
|
int rc;
|
||||||
const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers
|
const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers
|
||||||
const char *null_dev = " 2> /dev/null";
|
const char *null_dev = " 2> /dev/null";
|
||||||
char buf[1050];
|
char buf[1050];
|
||||||
snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev);
|
snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev);
|
||||||
rc = system(buf);
|
rc = system(buf);
|
||||||
if (rc)
|
if (rc)
|
||||||
system(buf+1); // call a strip utility from binutils
|
system(buf+1); // call a strip utility from binutils
|
||||||
}
|
}
|
||||||
the_end:
|
the_end:
|
||||||
tcc_free(s1->symtab_to_dynsym);
|
tcc_free(s1->symtab_to_dynsym);
|
||||||
|
|
338
tccgen.c
338
tccgen.c
|
@ -323,7 +323,7 @@ static void apply_visibility(Sym *sym, CType *type)
|
||||||
ElfW(Sym) *esym;
|
ElfW(Sym) *esym;
|
||||||
|
|
||||||
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
||||||
vis >>= VT_VIS_SHIFT;
|
vis >>= VT_VIS_SHIFT;
|
||||||
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
|
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1631,7 +1631,7 @@ static inline int is_null_pointer(SValue *p)
|
||||||
return 0;
|
return 0;
|
||||||
return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
|
return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
|
||||||
((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
|
((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
|
||||||
((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
|
((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int is_integer_btype(int bt)
|
static inline int is_integer_btype(int bt)
|
||||||
|
@ -1761,18 +1761,18 @@ ST_FUNC void gen_op(int op)
|
||||||
#if 0
|
#if 0
|
||||||
/* #ifdef CONFIG_TCC_BCHECK
|
/* #ifdef CONFIG_TCC_BCHECK
|
||||||
The main reason to removing this code:
|
The main reason to removing this code:
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main ()
|
int main ()
|
||||||
{
|
{
|
||||||
int v[10];
|
int v[10];
|
||||||
int i = 10;
|
int i = 10;
|
||||||
int j = 9;
|
int j = 9;
|
||||||
fprintf(stderr, "v+i-j = %p\n", v+i-j);
|
fprintf(stderr, "v+i-j = %p\n", v+i-j);
|
||||||
fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
|
fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
|
||||||
}
|
}
|
||||||
When this code is on. then the output looks like
|
When this code is on. then the output looks like
|
||||||
v+i-j = 0xfffffffe
|
v+i-j = 0xfffffffe
|
||||||
v+(i-j) = 0xbff84000
|
v+(i-j) = 0xbff84000
|
||||||
*/
|
*/
|
||||||
/* if evaluating constant expression, no code should be
|
/* if evaluating constant expression, no code should be
|
||||||
generated, so no bound check */
|
generated, so no bound check */
|
||||||
|
@ -2450,18 +2450,18 @@ static void gen_assign_cast(CType *dt)
|
||||||
dbt = dt->t & VT_BTYPE;
|
dbt = dt->t & VT_BTYPE;
|
||||||
sbt = st->t & VT_BTYPE;
|
sbt = st->t & VT_BTYPE;
|
||||||
if (sbt == VT_VOID || dbt == VT_VOID) {
|
if (sbt == VT_VOID || dbt == VT_VOID) {
|
||||||
if (sbt == VT_VOID && dbt == VT_VOID)
|
if (sbt == VT_VOID && dbt == VT_VOID)
|
||||||
; /*
|
; /*
|
||||||
It is Ok if both are void
|
It is Ok if both are void
|
||||||
A test program:
|
A test program:
|
||||||
void func1() {}
|
void func1() {}
|
||||||
void func2() {
|
void func2() {
|
||||||
return func1();
|
return func1();
|
||||||
}
|
}
|
||||||
gcc accepts this program
|
gcc accepts this program
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
tcc_error("cannot cast from/to void");
|
tcc_error("cannot cast from/to void");
|
||||||
}
|
}
|
||||||
if (dt->t & VT_CONSTANT)
|
if (dt->t & VT_CONSTANT)
|
||||||
tcc_warning("assignment of read-only location");
|
tcc_warning("assignment of read-only location");
|
||||||
|
@ -2542,7 +2542,7 @@ ST_FUNC void vstore(void)
|
||||||
dbt = ft & VT_BTYPE;
|
dbt = ft & VT_BTYPE;
|
||||||
if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
|
if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
|
||||||
(sbt == VT_INT && dbt == VT_SHORT))
|
(sbt == VT_INT && dbt == VT_SHORT))
|
||||||
&& !(vtop->type.t & VT_BITFIELD)) {
|
&& !(vtop->type.t & VT_BITFIELD)) {
|
||||||
/* optimize char/short casts */
|
/* optimize char/short casts */
|
||||||
delayed_cast = VT_MUSTCAST;
|
delayed_cast = VT_MUSTCAST;
|
||||||
vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
|
vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
|
||||||
|
@ -2764,20 +2764,20 @@ static void parse_attribute(AttributeDef *ad)
|
||||||
next();
|
next();
|
||||||
skip(')');
|
skip(')');
|
||||||
break;
|
break;
|
||||||
case TOK_VISIBILITY1:
|
case TOK_VISIBILITY1:
|
||||||
case TOK_VISIBILITY2:
|
case TOK_VISIBILITY2:
|
||||||
skip('(');
|
skip('(');
|
||||||
if (tok != TOK_STR)
|
if (tok != TOK_STR)
|
||||||
expect("visibility(\"default|hidden|internal|protected\")");
|
expect("visibility(\"default|hidden|internal|protected\")");
|
||||||
if (!strcmp (tokc.cstr->data, "default"))
|
if (!strcmp (tokc.cstr->data, "default"))
|
||||||
ad->a.visibility = STV_DEFAULT;
|
ad->a.visibility = STV_DEFAULT;
|
||||||
else if (!strcmp (tokc.cstr->data, "hidden"))
|
else if (!strcmp (tokc.cstr->data, "hidden"))
|
||||||
ad->a.visibility = STV_HIDDEN;
|
ad->a.visibility = STV_HIDDEN;
|
||||||
else if (!strcmp (tokc.cstr->data, "internal"))
|
else if (!strcmp (tokc.cstr->data, "internal"))
|
||||||
ad->a.visibility = STV_INTERNAL;
|
ad->a.visibility = STV_INTERNAL;
|
||||||
else if (!strcmp (tokc.cstr->data, "protected"))
|
else if (!strcmp (tokc.cstr->data, "protected"))
|
||||||
ad->a.visibility = STV_PROTECTED;
|
ad->a.visibility = STV_PROTECTED;
|
||||||
else
|
else
|
||||||
expect("visibility(\"default|hidden|internal|protected\")");
|
expect("visibility(\"default|hidden|internal|protected\")");
|
||||||
next();
|
next();
|
||||||
skip(')');
|
skip(')');
|
||||||
|
@ -2973,8 +2973,8 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
while (tok != '}') {
|
while (tok != '}') {
|
||||||
parse_btype(&btype, &ad);
|
parse_btype(&btype, &ad);
|
||||||
while (1) {
|
while (1) {
|
||||||
if (flexible)
|
if (flexible)
|
||||||
tcc_error("flexible array member '%s' not at the end of struct",
|
tcc_error("flexible array member '%s' not at the end of struct",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
bit_size = -1;
|
bit_size = -1;
|
||||||
v = 0;
|
v = 0;
|
||||||
|
@ -2982,21 +2982,21 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
if (tok != ':') {
|
if (tok != ':') {
|
||||||
type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
|
type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
if ((type1.t & VT_BTYPE) != VT_STRUCT)
|
if ((type1.t & VT_BTYPE) != VT_STRUCT)
|
||||||
expect("identifier");
|
expect("identifier");
|
||||||
else {
|
else {
|
||||||
int v = btype.ref->v;
|
int v = btype.ref->v;
|
||||||
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
|
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
|
||||||
if (tcc_state->ms_extensions == 0)
|
if (tcc_state->ms_extensions == 0)
|
||||||
expect("identifier");
|
expect("identifier");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type_size(&type1, &align) < 0) {
|
if (type_size(&type1, &align) < 0) {
|
||||||
if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
|
if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
|
||||||
flexible = 1;
|
flexible = 1;
|
||||||
else
|
else
|
||||||
tcc_error("field '%s' has incomplete type",
|
tcc_error("field '%s' has incomplete type",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
if ((type1.t & VT_BTYPE) == VT_FUNC ||
|
if ((type1.t & VT_BTYPE) == VT_FUNC ||
|
||||||
|
@ -3807,11 +3807,11 @@ ST_FUNC void unary(void)
|
||||||
gen_cast(&type);
|
gen_cast(&type);
|
||||||
}
|
}
|
||||||
} else if (tok == '{') {
|
} else if (tok == '{') {
|
||||||
/*
|
/*
|
||||||
if (nocode_wanted)
|
if (nocode_wanted)
|
||||||
tcc_error("statement expression in global scope"); */
|
tcc_error("statement expression in global scope"); */
|
||||||
/* this check breaks compilation of the linux 2.4.26 with the meesage:
|
/* this check breaks compilation of the linux 2.4.26 with the meesage:
|
||||||
linux/include/net/tcp.h:945: error: statement expression in global scope */
|
linux/include/net/tcp.h:945: error: statement expression in global scope */
|
||||||
|
|
||||||
/* save all registers */
|
/* save all registers */
|
||||||
save_regs(0);
|
save_regs(0);
|
||||||
|
@ -3872,12 +3872,12 @@ ST_FUNC void unary(void)
|
||||||
if ((vtop->type.t & VT_BTYPE) == VT_PTR)
|
if ((vtop->type.t & VT_BTYPE) == VT_PTR)
|
||||||
tcc_error("pointer not accepted for unary plus");
|
tcc_error("pointer not accepted for unary plus");
|
||||||
/* In order to force cast, we add zero, except for floating point
|
/* In order to force cast, we add zero, except for floating point
|
||||||
where we really need an noop (otherwise -0.0 will be transformed
|
where we really need an noop (otherwise -0.0 will be transformed
|
||||||
into +0.0). */
|
into +0.0). */
|
||||||
if (!is_float(vtop->type.t)) {
|
if (!is_float(vtop->type.t)) {
|
||||||
vpushi(0);
|
vpushi(0);
|
||||||
gen_op('+');
|
gen_op('+');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_SIZEOF:
|
case TOK_SIZEOF:
|
||||||
case TOK_ALIGNOF1:
|
case TOK_ALIGNOF1:
|
||||||
|
@ -4050,20 +4050,20 @@ ST_FUNC void unary(void)
|
||||||
next();
|
next();
|
||||||
unary();
|
unary();
|
||||||
t = vtop->type.t & VT_BTYPE;
|
t = vtop->type.t & VT_BTYPE;
|
||||||
if (is_float(t)) {
|
if (is_float(t)) {
|
||||||
/* In IEEE negate(x) isn't subtract(0,x), but rather
|
/* In IEEE negate(x) isn't subtract(0,x), but rather
|
||||||
subtract(-0, x). */
|
subtract(-0, x). */
|
||||||
vpush(&vtop->type);
|
vpush(&vtop->type);
|
||||||
if (t == VT_FLOAT)
|
if (t == VT_FLOAT)
|
||||||
vtop->c.f = -0.0f;
|
vtop->c.f = -0.0f;
|
||||||
else if (t == VT_DOUBLE)
|
else if (t == VT_DOUBLE)
|
||||||
vtop->c.d = -0.0;
|
vtop->c.d = -0.0;
|
||||||
else
|
else
|
||||||
vtop->c.ld = -0.0;
|
vtop->c.ld = -0.0;
|
||||||
} else
|
} else
|
||||||
vpushi(0);
|
vpushi(0);
|
||||||
vswap();
|
vswap();
|
||||||
gen_op('-');
|
gen_op('-');
|
||||||
break;
|
break;
|
||||||
case TOK_LAND:
|
case TOK_LAND:
|
||||||
if (!gnu_ext)
|
if (!gnu_ext)
|
||||||
|
@ -4142,7 +4142,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;
|
||||||
vtop->c.ptr_offset = 0;
|
vtop->c.ptr_offset = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4312,10 +4312,10 @@ ST_FUNC void unary(void)
|
||||||
|
|
||||||
|
|
||||||
size = type_size(&s->type, &align);
|
size = type_size(&s->type, &align);
|
||||||
/* We're writing whole regs often, make sure there's enough
|
/* We're writing whole regs often, make sure there's enough
|
||||||
space. Assume register size is power of 2. */
|
space. Assume register size is power of 2. */
|
||||||
if (regsize > align)
|
if (regsize > align)
|
||||||
align = regsize;
|
align = regsize;
|
||||||
loc = (loc - size) & -align;
|
loc = (loc - size) & -align;
|
||||||
addr = loc;
|
addr = loc;
|
||||||
#if defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_PE)
|
#if defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_PE)
|
||||||
|
@ -4610,16 +4610,16 @@ static void expr_cond(void)
|
||||||
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
|
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
|
||||||
type.t |= VT_UNSIGNED;
|
type.t |= VT_UNSIGNED;
|
||||||
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
} else if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
||||||
/* If one is a null ptr constant the result type
|
/* If one is a null ptr constant the result type
|
||||||
is the other. */
|
is the other. */
|
||||||
if (is_null_pointer (vtop))
|
if (is_null_pointer (vtop))
|
||||||
type = type1;
|
type = type1;
|
||||||
else if (is_null_pointer (&sv))
|
else if (is_null_pointer (&sv))
|
||||||
type = type2;
|
type = type2;
|
||||||
/* XXX: test pointer compatibility, C99 has more elaborate
|
/* XXX: test pointer compatibility, C99 has more elaborate
|
||||||
rules here. */
|
rules here. */
|
||||||
else
|
else
|
||||||
type = type1;
|
type = type1;
|
||||||
} else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
|
} else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
|
||||||
/* XXX: test function pointer compatibility */
|
/* XXX: test function pointer compatibility */
|
||||||
type = bt1 == VT_FUNC ? type1 : type2;
|
type = bt1 == VT_FUNC ? type1 : type2;
|
||||||
|
@ -4785,14 +4785,14 @@ static void label_or_decl(int l)
|
||||||
/* fast test first */
|
/* fast test first */
|
||||||
if (tok >= TOK_UIDENT)
|
if (tok >= TOK_UIDENT)
|
||||||
{
|
{
|
||||||
/* no need to save tokc because tok is an identifier */
|
/* no need to save tokc because tok is an identifier */
|
||||||
last_tok = tok;
|
last_tok = tok;
|
||||||
next();
|
next();
|
||||||
if (tok == ':') {
|
if (tok == ':') {
|
||||||
unget_tok(last_tok);
|
unget_tok(last_tok);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unget_tok(last_tok);
|
unget_tok(last_tok);
|
||||||
}
|
}
|
||||||
decl(l);
|
decl(l);
|
||||||
}
|
}
|
||||||
|
@ -4891,10 +4891,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
Sym *p;
|
Sym *p;
|
||||||
switch(vtop->type.t & VT_BTYPE) {
|
switch(vtop->type.t & VT_BTYPE) {
|
||||||
/* case VT_PTR: */
|
/* case VT_PTR: */
|
||||||
/* this breaks a compilation of the linux kernel v2.4.26 */
|
/* this breaks a compilation of the linux kernel v2.4.26 */
|
||||||
/* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
|
/* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
|
||||||
/* Look a commit a80acab: Display error on statement expressions with complex return type */
|
/* Look a commit a80acab: Display error on statement expressions with complex return type */
|
||||||
/* A pointer is not a complex return type */
|
/* A pointer is not a complex return type */
|
||||||
case VT_STRUCT:
|
case VT_STRUCT:
|
||||||
case VT_ENUM:
|
case VT_ENUM:
|
||||||
case VT_FUNC:
|
case VT_FUNC:
|
||||||
|
@ -5642,38 +5642,38 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
AttributeDef ad1;
|
AttributeDef ad1;
|
||||||
CType type1;
|
CType type1;
|
||||||
next();
|
next();
|
||||||
if (tcc_state->old_struct_init_code) {
|
if (tcc_state->old_struct_init_code) {
|
||||||
/* an old version of struct initialization.
|
/* an old version of struct initialization.
|
||||||
It have a problems. But with a new version
|
It have a problems. But with a new version
|
||||||
linux 2.4.26 can't load ramdisk.
|
linux 2.4.26 can't load ramdisk.
|
||||||
*/
|
*/
|
||||||
while (tok == '(') {
|
while (tok == '(') {
|
||||||
par_count++;
|
par_count++;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
if (!parse_btype(&type1, &ad1))
|
if (!parse_btype(&type1, &ad1))
|
||||||
expect("cast");
|
expect("cast");
|
||||||
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
|
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
|
||||||
#if 0
|
#if 0
|
||||||
if (!is_assignable_types(type, &type1))
|
if (!is_assignable_types(type, &type1))
|
||||||
tcc_error("invalid type for cast");
|
tcc_error("invalid type for cast");
|
||||||
#endif
|
#endif
|
||||||
skip(')');
|
skip(')');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tok != '(') {
|
if (tok != '(') {
|
||||||
if (!parse_btype(&type1, &ad1))
|
if (!parse_btype(&type1, &ad1))
|
||||||
expect("cast");
|
expect("cast");
|
||||||
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
|
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
|
||||||
#if 0
|
#if 0
|
||||||
if (!is_assignable_types(type, &type1))
|
if (!is_assignable_types(type, &type1))
|
||||||
tcc_error("invalid type for cast");
|
tcc_error("invalid type for cast");
|
||||||
#endif
|
#endif
|
||||||
skip(')');
|
skip(')');
|
||||||
} else
|
} else
|
||||||
unget_tok(tok);
|
unget_tok(tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
no_oblock = 1;
|
no_oblock = 1;
|
||||||
|
@ -5699,28 +5699,28 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
|
|
||||||
/* gr: skip fields from same union - ugly. */
|
/* gr: skip fields from same union - ugly. */
|
||||||
while (f->next) {
|
while (f->next) {
|
||||||
int align = 0;
|
int align = 0;
|
||||||
int f_size = type_size(&f->type, &align);
|
int f_size = type_size(&f->type, &align);
|
||||||
int f_type = (f->type.t & VT_BTYPE);
|
int f_type = (f->type.t & VT_BTYPE);
|
||||||
|
|
||||||
///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
|
///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
|
||||||
/* test for same offset */
|
/* test for same offset */
|
||||||
if (f->next->c != f->c)
|
if (f->next->c != f->c)
|
||||||
break;
|
break;
|
||||||
if ((f_type == VT_STRUCT) && (f_size == 0)) {
|
if ((f_type == VT_STRUCT) && (f_size == 0)) {
|
||||||
/*
|
/*
|
||||||
Lets assume a structure of size 0 can't be a member of the union.
|
Lets assume a structure of size 0 can't be a member of the union.
|
||||||
This allow to compile the following code from a linux kernel v2.4.26
|
This allow to compile the following code from a linux kernel v2.4.26
|
||||||
typedef struct { } rwlock_t;
|
typedef struct { } rwlock_t;
|
||||||
struct fs_struct {
|
struct fs_struct {
|
||||||
int count;
|
int count;
|
||||||
rwlock_t lock;
|
rwlock_t lock;
|
||||||
int umask;
|
int umask;
|
||||||
};
|
};
|
||||||
struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
|
struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
|
||||||
tcc-0.9.23 can succesfully compile this version of the kernel.
|
tcc-0.9.23 can succesfully compile this version of the kernel.
|
||||||
gcc don't have problems with this code too.
|
gcc don't have problems with this code too.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if yes, test for bitfield shift */
|
/* if yes, test for bitfield shift */
|
||||||
|
@ -5760,21 +5760,21 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
/* just skip expression */
|
/* just skip expression */
|
||||||
parlevel = parlevel1 = 0;
|
parlevel = parlevel1 = 0;
|
||||||
while ((parlevel > 0 || parlevel1 > 0 ||
|
while ((parlevel > 0 || parlevel1 > 0 ||
|
||||||
(tok != '}' && tok != ',')) && tok != -1) {
|
(tok != '}' && tok != ',')) && tok != -1) {
|
||||||
if (tok == '(')
|
if (tok == '(')
|
||||||
parlevel++;
|
parlevel++;
|
||||||
else if (tok == ')') {
|
else if (tok == ')') {
|
||||||
if (parlevel == 0 && parlevel1 == 0)
|
if (parlevel == 0 && parlevel1 == 0)
|
||||||
break;
|
break;
|
||||||
parlevel--;
|
parlevel--;
|
||||||
}
|
}
|
||||||
else if (tok == '{')
|
else if (tok == '{')
|
||||||
parlevel1++;
|
parlevel1++;
|
||||||
else if (tok == '}') {
|
else if (tok == '}') {
|
||||||
if (parlevel == 0 && parlevel1 == 0)
|
if (parlevel == 0 && parlevel1 == 0)
|
||||||
break;
|
break;
|
||||||
parlevel1--;
|
parlevel1--;
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -5995,12 +5995,12 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
} else {
|
} else {
|
||||||
/* push global reference */
|
/* push global reference */
|
||||||
sym = get_sym_ref(type, sec, addr, size);
|
sym = get_sym_ref(type, sec, addr, size);
|
||||||
vpushsym(type, sym);
|
vpushsym(type, sym);
|
||||||
}
|
}
|
||||||
/* patch symbol weakness */
|
/* patch symbol weakness */
|
||||||
if (type->t & VT_WEAK)
|
if (type->t & VT_WEAK)
|
||||||
weaken_symbol(sym);
|
weaken_symbol(sym);
|
||||||
apply_visibility(sym, type);
|
apply_visibility(sym, type);
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
/* handles bounds now because the symbol must be defined
|
/* handles bounds now because the symbol must be defined
|
||||||
before for the relocation */
|
before for the relocation */
|
||||||
|
@ -6236,11 +6236,11 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
if (((btype.t & VT_BTYPE) == VT_ENUM ||
|
if (((btype.t & VT_BTYPE) == VT_ENUM ||
|
||||||
(btype.t & VT_BTYPE) == VT_STRUCT) &&
|
(btype.t & VT_BTYPE) == VT_STRUCT) &&
|
||||||
tok == ';') {
|
tok == ';') {
|
||||||
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
|
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
int v = btype.ref->v;
|
int v = btype.ref->v;
|
||||||
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
|
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
|
||||||
tcc_warning("unnamed struct/union that defines no instances");
|
tcc_warning("unnamed struct/union that defines no instances");
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -6286,7 +6286,7 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
if (ad.a.func_export)
|
if (ad.a.func_export)
|
||||||
type.t |= VT_EXPORT;
|
type.t |= VT_EXPORT;
|
||||||
#endif
|
#endif
|
||||||
type.t |= ad.a.visibility << VT_VIS_SHIFT;
|
type.t |= ad.a.visibility << VT_VIS_SHIFT;
|
||||||
|
|
||||||
if (tok == '{') {
|
if (tok == '{') {
|
||||||
if (l == VT_LOCAL)
|
if (l == VT_LOCAL)
|
||||||
|
@ -6327,10 +6327,10 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
if (sym->type.t & VT_STATIC)
|
if (sym->type.t & VT_STATIC)
|
||||||
type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
|
type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
|
||||||
|
|
||||||
/* If the definition has no visibility use the
|
/* If the definition has no visibility use the
|
||||||
one from prototype. */
|
one from prototype. */
|
||||||
if (! (type.t & VT_VIS_MASK))
|
if (! (type.t & VT_VIS_MASK))
|
||||||
type.t |= sym->type.t & VT_VIS_MASK;
|
type.t |= sym->type.t & VT_VIS_MASK;
|
||||||
|
|
||||||
if (!is_compatible_types(&sym->type, &type)) {
|
if (!is_compatible_types(&sym->type, &type)) {
|
||||||
func_error1:
|
func_error1:
|
||||||
|
|
48
tccpe.c
48
tccpe.c
|
@ -398,22 +398,22 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
|
||||||
s = pe_export_name(s1, sym);
|
s = pe_export_name(s1, sym);
|
||||||
if (n) {
|
if (n) {
|
||||||
/* second try: */
|
/* second try: */
|
||||||
if (sym->st_other & ST_PE_STDCALL) {
|
if (sym->st_other & ST_PE_STDCALL) {
|
||||||
/* try w/0 stdcall deco (windows API convention) */
|
/* try w/0 stdcall deco (windows API convention) */
|
||||||
p = strrchr(s, '@');
|
p = strrchr(s, '@');
|
||||||
if (!p || s[0] != '_')
|
if (!p || s[0] != '_')
|
||||||
break;
|
break;
|
||||||
strcpy(buffer, s+1)[p-s-1] = 0;
|
strcpy(buffer, s+1)[p-s-1] = 0;
|
||||||
} else if (s[0] != '_') { /* try non-ansi function */
|
} else if (s[0] != '_') { /* try non-ansi function */
|
||||||
buffer[0] = '_', strcpy(buffer + 1, s);
|
buffer[0] = '_', strcpy(buffer + 1, s);
|
||||||
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
|
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
|
||||||
strcpy(buffer, s + 6);
|
strcpy(buffer, s + 6);
|
||||||
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
|
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
|
||||||
strcpy(buffer, s + 6);
|
strcpy(buffer, s + 6);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s = buffer;
|
s = buffer;
|
||||||
}
|
}
|
||||||
sym_index = find_elf_sym(s1->dynsymtab_section, s);
|
sym_index = find_elf_sym(s1->dynsymtab_section, s);
|
||||||
// printf("find (%d) %d %s\n", n, sym_index, s);
|
// printf("find (%d) %d %s\n", n, sym_index, s);
|
||||||
|
@ -565,9 +565,9 @@ static int pe_write(struct pe_info *pe)
|
||||||
#endif
|
#endif
|
||||||
/* NT additional fields. */
|
/* NT additional fields. */
|
||||||
#if defined(TCC_TARGET_ARM)
|
#if defined(TCC_TARGET_ARM)
|
||||||
0x00100000, /*DWORD ImageBase; */
|
0x00100000, /*DWORD ImageBase; */
|
||||||
#else
|
#else
|
||||||
0x00400000, /*DWORD ImageBase; */
|
0x00400000, /*DWORD ImageBase; */
|
||||||
#endif
|
#endif
|
||||||
0x00001000, /*DWORD SectionAlignment; */
|
0x00001000, /*DWORD SectionAlignment; */
|
||||||
0x00000200, /*DWORD FileAlignment; */
|
0x00000200, /*DWORD FileAlignment; */
|
||||||
|
@ -1841,13 +1841,13 @@ ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
|
||||||
pe.subsystem = s1->pe_subsystem;
|
pe.subsystem = s1->pe_subsystem;
|
||||||
|
|
||||||
/* set default file/section alignment */
|
/* set default file/section alignment */
|
||||||
if (pe.subsystem == 1) {
|
if (pe.subsystem == 1) {
|
||||||
pe.section_align = 0x20;
|
pe.section_align = 0x20;
|
||||||
pe.file_align = 0x20;
|
pe.file_align = 0x20;
|
||||||
} else {
|
} else {
|
||||||
pe.section_align = 0x1000;
|
pe.section_align = 0x1000;
|
||||||
pe.file_align = 0x200;
|
pe.file_align = 0x200;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s1->section_align != 0)
|
if (s1->section_align != 0)
|
||||||
pe.section_align = s1->section_align;
|
pe.section_align = s1->section_align;
|
||||||
|
|
8
tccpp.c
8
tccpp.c
|
@ -786,7 +786,7 @@ redo_start:
|
||||||
else if (tok == TOK_LINEFEED)
|
else if (tok == TOK_LINEFEED)
|
||||||
goto redo_start;
|
goto redo_start;
|
||||||
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p);
|
||||||
break;
|
break;
|
||||||
_default:
|
_default:
|
||||||
default:
|
default:
|
||||||
|
@ -1786,7 +1786,7 @@ _line_num:
|
||||||
total_lines += file->line_num - n;
|
total_lines += file->line_num - n;
|
||||||
file->line_num = n;
|
file->line_num = n;
|
||||||
if (s1->do_debug)
|
if (s1->do_debug)
|
||||||
put_stabs(file->filename, N_BINCL, 0, 0, 0);
|
put_stabs(file->filename, N_BINCL, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
case TOK_WARNING:
|
case TOK_WARNING:
|
||||||
|
@ -2272,7 +2272,7 @@ static void parse_number(const char *p)
|
||||||
if (n & 0xffffffff00000000LL || must_64bit) {
|
if (n & 0xffffffff00000000LL || must_64bit) {
|
||||||
tok = TOK_CLLONG;
|
tok = TOK_CLLONG;
|
||||||
n1 = n >> 32;
|
n1 = n >> 32;
|
||||||
} else {
|
} else {
|
||||||
tok = TOK_CINT;
|
tok = TOK_CINT;
|
||||||
n1 = n;
|
n1 = n;
|
||||||
}
|
}
|
||||||
|
@ -2538,7 +2538,7 @@ maybe_newline:
|
||||||
} else if (c == '.') {
|
} else if (c == '.') {
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c != '.')
|
if (c != '.')
|
||||||
expect("'.'");
|
expect("'.'");
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
tok = TOK_DOTS;
|
tok = TOK_DOTS;
|
||||||
} else {
|
} else {
|
||||||
|
|
18
tccrun.c
18
tccrun.c
|
@ -127,7 +127,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||||
for (i=0; i<argc; ++i)
|
for (i=0; i<argc; ++i)
|
||||||
bound_new_region(argv[i], strlen(argv[i]));
|
bound_new_region(argv[i], strlen(argv[i]));
|
||||||
|
|
||||||
errno = 0; /* clean errno value */
|
errno = 0; /* clean errno value */
|
||||||
ret = (*prog_main)(argc, argv);
|
ret = (*prog_main)(argc, argv);
|
||||||
|
|
||||||
/* unmark argv area */
|
/* unmark argv area */
|
||||||
|
@ -139,7 +139,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
errno = 0; /* clean errno value */
|
errno = 0; /* clean errno value */
|
||||||
ret = (*prog_main)(argc, argv);
|
ret = (*prog_main)(argc, argv);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -652,7 +652,7 @@ static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
|
||||||
if (rt_bound_error_msg && *rt_bound_error_msg)
|
if (rt_bound_error_msg && *rt_bound_error_msg)
|
||||||
rt_error(uc, *rt_bound_error_msg);
|
rt_error(uc, *rt_bound_error_msg);
|
||||||
else
|
else
|
||||||
rt_error(uc, "access violation");
|
rt_error(uc, "access violation");
|
||||||
break;
|
break;
|
||||||
case EXCEPTION_STACK_OVERFLOW:
|
case EXCEPTION_STACK_OVERFLOW:
|
||||||
rt_error(uc, "stack overflow");
|
rt_error(uc, "stack overflow");
|
||||||
|
@ -697,12 +697,12 @@ static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
|
||||||
fp = uc->Ebp;
|
fp = uc->Ebp;
|
||||||
#endif
|
#endif
|
||||||
if (level > 0) {
|
if (level > 0) {
|
||||||
for(i=1;i<level;i++) {
|
for(i = 1; i < level; i++) {
|
||||||
/* XXX: check address validity with program info */
|
/* XXX: check address validity with program info */
|
||||||
if (fp <= 0x1000 || fp >= 0xc0000000)
|
if (fp <= 0x1000 || fp >= 0xc0000000)
|
||||||
return -1;
|
return -1;
|
||||||
fp = ((addr_t*)fp)[0];
|
fp = ((addr_t*)fp)[0];
|
||||||
}
|
}
|
||||||
pc = ((addr_t*)fp)[1];
|
pc = ((addr_t*)fp)[1];
|
||||||
}
|
}
|
||||||
*paddr = pc;
|
*paddr = pc;
|
||||||
|
|
71
x86_64-gen.c
71
x86_64-gen.c
|
@ -477,18 +477,17 @@ void load(int r, SValue *sv)
|
||||||
gen_modrm(r, VT_LOCAL, sv->sym, fc);
|
gen_modrm(r, VT_LOCAL, sv->sym, fc);
|
||||||
} else if (v == VT_CMP) {
|
} else if (v == VT_CMP) {
|
||||||
orex(0,r,0,0);
|
orex(0,r,0,0);
|
||||||
if ((fc & ~0x100) != TOK_NE)
|
if ((fc & ~0x100) != TOK_NE)
|
||||||
oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
|
oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
|
||||||
else
|
else
|
||||||
oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
|
oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
|
||||||
if (fc & 0x100)
|
if (fc & 0x100) {
|
||||||
{
|
/* This was a float compare. If the parity bit is
|
||||||
/* This was a float compare. If the parity bit is
|
* set the result was unordered, meaning false for everything
|
||||||
set the result was unordered, meaning false for everything
|
* except TOK_NE, and true for TOK_NE. */
|
||||||
except TOK_NE, and true for TOK_NE. */
|
fc &= ~0x100;
|
||||||
fc &= ~0x100;
|
o(0x037a + (REX_BASE(r) << 8));
|
||||||
o(0x037a + (REX_BASE(r) << 8));
|
}
|
||||||
}
|
|
||||||
orex(0,r,0, 0x0f); /* setxx %br */
|
orex(0,r,0, 0x0f); /* setxx %br */
|
||||||
o(fc);
|
o(fc);
|
||||||
o(0xc0 + REG_VALUE(r));
|
o(0xc0 + REG_VALUE(r));
|
||||||
|
@ -619,7 +618,7 @@ static void gcall_or_jmp(int is_jmp)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
||||||
((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) {
|
((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) {
|
||||||
/* constant case */
|
/* constant case */
|
||||||
if (vtop->r & VT_SYM) {
|
if (vtop->r & VT_SYM) {
|
||||||
/* relocation case */
|
/* relocation case */
|
||||||
|
@ -1705,7 +1704,7 @@ void gfunc_prolog(CType *func_type)
|
||||||
param_addr = addr;
|
param_addr = addr;
|
||||||
addr += size;
|
addr += size;
|
||||||
break;
|
break;
|
||||||
default: break; /* nothing to be done for x86_64_mode_none */
|
default: break; /* nothing to be done for x86_64_mode_none */
|
||||||
}
|
}
|
||||||
sym_push(sym->v & ~SYM_FIELD, type,
|
sym_push(sym->v & ~SYM_FIELD, type,
|
||||||
VT_LOCAL | VT_LVAL, param_addr);
|
VT_LOCAL | VT_LVAL, param_addr);
|
||||||
|
@ -1717,8 +1716,8 @@ void gfunc_prolog(CType *func_type)
|
||||||
func_bound_offset = lbounds_section->data_offset;
|
func_bound_offset = lbounds_section->data_offset;
|
||||||
func_bound_ind = ind;
|
func_bound_ind = ind;
|
||||||
oad(0xb8, 0); /* lbound section pointer */
|
oad(0xb8, 0); /* lbound section pointer */
|
||||||
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
||||||
oad(0xb8, 0); /* call to function */
|
oad(0xb8, 0); /* call to function */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1730,7 +1729,7 @@ void gfunc_epilog(void)
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (tcc_state->do_bounds_check
|
if (tcc_state->do_bounds_check
|
||||||
&& func_bound_offset != lbounds_section->data_offset)
|
&& func_bound_offset != lbounds_section->data_offset)
|
||||||
{
|
{
|
||||||
addr_t saved_ind;
|
addr_t saved_ind;
|
||||||
addr_t *bounds_ptr;
|
addr_t *bounds_ptr;
|
||||||
|
@ -1754,7 +1753,7 @@ void gfunc_epilog(void)
|
||||||
o(0x5250); /* save returned value, if any */
|
o(0x5250); /* save returned value, if any */
|
||||||
greloc(cur_text_section, sym_data, ind + 1, R_386_32);
|
greloc(cur_text_section, sym_data, ind + 1, R_386_32);
|
||||||
oad(0xb8, 0); /* mov xxx, %rax */
|
oad(0xb8, 0); /* mov xxx, %rax */
|
||||||
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
||||||
gen_static_call(TOK___bound_local_delete);
|
gen_static_call(TOK___bound_local_delete);
|
||||||
o(0x585a); /* restore returned value, if any */
|
o(0x585a); /* restore returned value, if any */
|
||||||
}
|
}
|
||||||
|
@ -1806,24 +1805,24 @@ int gtst(int inv, int t)
|
||||||
v = vtop->r & VT_VALMASK;
|
v = vtop->r & VT_VALMASK;
|
||||||
if (v == VT_CMP) {
|
if (v == VT_CMP) {
|
||||||
/* fast case : can jump directly since flags are set */
|
/* fast case : can jump directly since flags are set */
|
||||||
if (vtop->c.i & 0x100)
|
if (vtop->c.i & 0x100)
|
||||||
{
|
{
|
||||||
/* This was a float compare. If the parity flag is set
|
/* This was a float compare. If the parity flag is set
|
||||||
the result was unordered. For anything except != this
|
the result was unordered. For anything except != this
|
||||||
means false and we don't jump (anding both conditions).
|
means false and we don't jump (anding both conditions).
|
||||||
For != this means true (oring both).
|
For != this means true (oring both).
|
||||||
Take care about inverting the test. We need to jump
|
Take care about inverting the test. We need to jump
|
||||||
to our target if the result was unordered and test wasn't NE,
|
to our target if the result was unordered and test wasn't NE,
|
||||||
otherwise if unordered we don't want to jump. */
|
otherwise if unordered we don't want to jump. */
|
||||||
vtop->c.i &= ~0x100;
|
vtop->c.i &= ~0x100;
|
||||||
if (!inv == (vtop->c.i != TOK_NE))
|
if (!inv == (vtop->c.i != TOK_NE))
|
||||||
o(0x067a); /* jp +6 */
|
o(0x067a); /* jp +6 */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g(0x0f);
|
g(0x0f);
|
||||||
t = psym(0x8a, t); /* jp t */
|
t = psym(0x8a, t); /* jp t */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g(0x0f);
|
g(0x0f);
|
||||||
t = psym((vtop->c.i - 16) ^ inv, t);
|
t = psym((vtop->c.i - 16) ^ inv, t);
|
||||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
} else if (v == VT_JMP || v == VT_JMPI) {
|
||||||
|
|
Loading…
Reference in a new issue