Fix formatting breakage from "rogue tabs" commit.

This commit is contained in:
gus knight 2015-07-29 09:54:03 -04:00
parent 271abe7117
commit 7f5b95ea32
9 changed files with 403 additions and 405 deletions

View file

@ -43,26 +43,26 @@ 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_R0 0x0004 #define RC_R0 0x0004
#define RC_R1 0x0008 #define RC_R1 0x0008
#define RC_R2 0x0010 #define RC_R2 0x0010
#define RC_R3 0x0020 #define RC_R3 0x0020
#define RC_R12 0x0040 #define RC_R12 0x0040
#define RC_F0 0x0080 #define RC_F0 0x0080
#define RC_F1 0x0100 #define RC_F1 0x0100
#define RC_F2 0x0200 #define RC_F2 0x0200
#define RC_F3 0x0400 #define RC_F3 0x0400
#ifdef TCC_ARM_VFP #ifdef TCC_ARM_VFP
#define RC_F4 0x0800 #define RC_F4 0x0800
#define RC_F5 0x1000 #define RC_F5 0x1000
#define RC_F6 0x2000 #define RC_F6 0x2000
#define RC_F7 0x4000 #define RC_F7 0x4000
#endif #endif
#define RC_IRET RC_R0 /* function return: integer register */ #define RC_IRET RC_R0 /* function return: integer register */
#define RC_LRET RC_R1 /* function return: second integer register */ #define RC_LRET RC_R1 /* function return: second integer register */
#define RC_FRET RC_F0 /* function return: float register */ #define RC_FRET RC_F0 /* function return: float register */
/* pretty names for the registers */ /* pretty names for the registers */
enum { enum {
@ -1716,12 +1716,12 @@ void gen_opf(int op)
} }
if (is_zero(-1)) { if (is_zero(-1)) {
vswap(); vswap();
switch(op) { switch(op) {
case TOK_LT: op = TOK_GT; break; case TOK_LT: op = TOK_GT; break;
case TOK_GE: op = TOK_ULE; break; case TOK_GE: op = TOK_ULE; break;
case TOK_LE: op = TOK_GE; break; case TOK_LE: op = TOK_GE; break;
case TOK_GT: op = TOK_ULT; break; case TOK_GT: op = TOK_ULT; break;
} }
} }
x |= 0xB40040; /* fcmpX */ x |= 0xB40040; /* fcmpX */
if (op != TOK_EQ && op != TOK_NE) if (op != TOK_EQ && op != TOK_NE)
@ -1738,12 +1738,12 @@ void gen_opf(int op)
} }
o(0xEEF1FA10); /* fmstat */ o(0xEEF1FA10); /* fmstat */
switch(op) { switch(op) {
case TOK_LE: op = TOK_ULE; break; case TOK_LE: op = TOK_ULE; break;
case TOK_LT: op = TOK_ULT; break; case TOK_LT: op = TOK_ULT; break;
case TOK_UGE: op = TOK_GE; break; case TOK_UGE: op = TOK_GE; break;
case TOK_UGT: op = TOK_GT; break; case TOK_UGT: op = TOK_GT; break;
} }
vtop->r = VT_CMP; vtop->r = VT_CMP;
vtop->c.i = op; vtop->c.i = op;

View file

@ -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] = '_';
@ -2257,7 +2257,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
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;

View file

@ -492,25 +492,25 @@ static void asm_parse_directive(TCCState *s1)
case TOK_ASM_global: case TOK_ASM_global:
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();
sym = label_find(tok); sym = label_find(tok);
if (!sym) { if (!sym) {
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,12 +536,12 @@ 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;
@ -552,8 +552,8 @@ static void asm_parse_directive(TCCState *s1)
} }
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];

View file

@ -21,9 +21,9 @@
#include "tcc.h" #include "tcc.h"
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */ #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
#define MAX_STR_TABLE 1000000 #define MAX_STR_TABLE 1000000
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */ AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
SCNHDR section_header[MAXNSCNS]; SCNHDR section_header[MAXNSCNS];
@ -94,21 +94,21 @@ ST_FUNC int tcc_output_coff(TCCState* s1, FILE* f)
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym); nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1"); coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */ file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
file_hdr.f_timdat = 0; /* time & date stamp */ file_hdr.f_timdat = 0; /* time & date stamp */
file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */ file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */ file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */ file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
o_filehdr.magic = 0x0108; /* see magic.h */ o_filehdr.magic = 0x0108; /* see magic.h */
o_filehdr.vstamp = 0x0190; /* version stamp */ o_filehdr.vstamp = 0x0190; /* version stamp */
o_filehdr.tsize = o_filehdr.tsize =
stext->data_offset; /* text size in bytes, padded to FW bdry */ stext->data_offset; /* text size in bytes, padded to FW bdry */
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */ o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */ o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */ o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */ o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */ o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
// create all the section headers // create all the section headers

View file

@ -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);
@ -801,17 +801,17 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
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,21 +917,21 @@ 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) {
tcc_error("internal error: relocation failed"); tcc_error("internal error: relocation failed");
}
*(int *)ptr += diff;
} }
*(int *)ptr += diff;
}
break; break;
case R_X86_64_GLOB_DAT: case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT: case R_X86_64_JUMP_SLOT:
@ -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,20 +1171,20 @@ 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) {
Section *plt; Section *plt;
@ -1220,9 +1220,9 @@ 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)
if (need_plt_entry) { if (need_plt_entry) {
Section *plt; Section *plt;
@ -1250,29 +1250,29 @@ 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);
} }
/* And now create the GOT slot itself. */ /* And now create the GOT slot itself. */
ptr = section_ptr_add(s1->got, PTR_SIZE); ptr = section_ptr_add(s1->got, PTR_SIZE);
*ptr = 0; *ptr = 0;
if (need_plt_entry) if (need_plt_entry)
return symattr->plt_offset; return symattr->plt_offset;
else else
return symattr->got_offset; return symattr->got_offset;
} }
/* build GOT and PLT entries */ /* build GOT and PLT entries */
@ -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,20 +1397,20 @@ 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)
@ -1455,7 +1455,7 @@ ST_FUNC void build_got_entries(TCCState *s1)
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)
@ -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,16 +1587,16 @@ 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);

View file

@ -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;
@ -2990,14 +2990,14 @@ static void struct_decl(CType *type, int u, int tdef)
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 ||
(type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
@ -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;
@ -4783,17 +4783,16 @@ static void label_or_decl(int l)
int last_tok; int last_tok;
/* 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);
return;
}
unget_tok(last_tok); unget_tok(last_tok);
return;
} }
unget_tok(last_tok);
}
decl(l); decl(l);
} }
@ -4891,10 +4890,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 +5641,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))
expect("cast");
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
#if 0
if (!is_assignable_types(type, &type1))
tcc_error("invalid type for cast");
#endif
skip(')');
}
else
{
if (tok != '(') {
if (!parse_btype(&type1, &ad1)) if (!parse_btype(&type1, &ad1))
expect("cast");
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
#if 0
if (!is_assignable_types(type, &type1))
tcc_error("invalid type for cast");
#endif
skip(')');
}
else
{
if (tok != '(') {
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 +5698,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 +5759,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 +5994,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 +6235,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 +6285,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 +6326,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:

View file

@ -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;
strcpy(buffer, s+1)[p-s-1] = 0;
} else if (s[0] != '_') { /* try non-ansi function */
buffer[0] = '_', strcpy(buffer + 1, s);
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
strcpy(buffer, s + 6);
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
strcpy(buffer, s + 6);
} else {
break; break;
strcpy(buffer, s+1)[p-s-1] = 0; }
} else if (s[0] != '_') { /* try non-ansi function */ s = buffer;
buffer[0] = '_', strcpy(buffer + 1, s);
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
strcpy(buffer, s + 6);
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
strcpy(buffer, s + 6);
} else {
break;
}
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; */

View file

@ -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;
} }
} }

View file

@ -618,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 */
@ -1806,7 +1806,7 @@ int gtst(int inv, int t)
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).
@ -1816,13 +1816,12 @@ int gtst(int inv, int t)
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) {