提交 d348a9a5 编辑于 作者: grischka's avatar grischka
浏览文件

final update for 0.9.27

tccgen.c:
- fix ldouble asm hack
- fix a VLA problem on Win64 (also x86_64-gen.c)
- patch_type(): make sure that no symbol ever changes
  from global to static

tcc.c:
- tcc -vv: print libtcc1.a path also on win32

tccpe.c, tcctools.c:
- use unix LF mode to for .def output files (that is for
  creating reproducible output trees)

Makefile:
- suppress some warnings when makeinfo is missing
- call 'which install' only on win32

tests/Makefile:
- change PATH only on WINNT systems (i.e. not if cross-compiling
  on linux for win32)
- asm-c-connect.test: slim output and do diff

tccrun.c tccpe.c *-link.c:
- integrate former 'pe_relocate_rva()' into normal relocation
  This also fixes linkage of the unwind data on WIN64 for -run
  (reported by Janus Lynggaard Thorborg)

tccasm.c, tests/tcctest.c:
- fix dot (sym_index of -1 crashed in put_elf_reloc)
- massage .set a bit (see test)

other:
- #define SECTION_ABS removed
- ST_DATA Section *strtab_section: removed
- put_extern_sym2(): take int section number

Conflicts:
	tccelf.c
	tccpe.c

Conflicts:
	tccelf.c
上级 1a4d4b76
...@@ -41,16 +41,17 @@ win32/include/stddef.h ...@@ -41,16 +41,17 @@ win32/include/stddef.h
win32/include/varargs.h win32/include/varargs.h
win32/include/tcclib.h win32/include/tcclib.h
tests/test.out*
tests/test*.out
tests/tcctest[1234] tests/tcctest[1234]
tests/tcctest.gcc tests/tcctest.gcc
tests/*.out*
tests/*.ref tests/*.ref
tests/*.txt tests/*.txt
tests/*.gcc tests/*.gcc
tests/*-cc* tests/*-cc*
tests/*-tcc* tests/*-tcc*
tests/libtcc_test tests/libtcc_test
tests/asm-c-connect
tests/asm-c-connect-sep
tests/vla_test tests/vla_test
tests/hello tests/hello
tests/tests2/fred.txt tests/tests2/fred.txt
...@@ -239,14 +239,15 @@ FORCE: ...@@ -239,14 +239,15 @@ FORCE:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# documentation and man page # documentation and man page
tcc-doc.html: tcc-doc.texi tcc-doc.html: tcc-doc.texi
-makeinfo --no-split --html --number-sections -o $@ $< makeinfo --no-split --html --number-sections -o $@ $< || true
tcc.1: tcc-doc.texi tcc.1: tcc-doc.texi
-$(TOPSRC)/texi2pod.pl $< tcc.pod $(TOPSRC)/texi2pod.pl $< tcc.pod \
-pod2man --section=1 --center="Tiny C Compiler" --release="$(VERSION)" tcc.pod > $@ && pod2man --section=1 --center="Tiny C Compiler" --release="$(VERSION)" tcc.pod >tmp.1 \
&& mv tmp.1 $@ || rm -f tmp.1
tcc-doc.info: tcc-doc.texi tcc-doc.info: tcc-doc.texi
-makeinfo $< makeinfo $< || true
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# install # install
...@@ -304,7 +305,7 @@ ifneq "$(wildcard $(LIBTCC1_U))" "" ...@@ -304,7 +305,7 @@ ifneq "$(wildcard $(LIBTCC1_U))" ""
endif endif
# the msys-git shell works to configure && make except it does not have install # the msys-git shell works to configure && make except it does not have install
ifeq ($(CONFIG_WIN32)-$(shell which install >/dev/null 2>&1 || echo no),yes-no) ifeq "$(and $(CONFIG_WIN32),$(shell which install >/dev/null 2>&1 || echo no))" "no"
install-win : INSTALL = cp install-win : INSTALL = cp
install-win : INSTALLBIN = cp install-win : INSTALLBIN = cp
endif endif
...@@ -349,10 +350,10 @@ tests2.%: ...@@ -349,10 +350,10 @@ tests2.%:
$(MAKE) -C tests/tests2 $@ $(MAKE) -C tests/tests2 $@
clean: clean:
rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod
rm -f *~ *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS rm -f *~ *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS
@$(MAKE) -C tests $@
@$(MAKE) -C lib $@ @$(MAKE) -C lib $@
@$(MAKE) -C tests $@
distclean: clean distclean: clean
rm -f config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html rm -f config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
......
...@@ -382,6 +382,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t ...@@ -382,6 +382,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
/* Nothing to do. Normally used to indicate a dependency /* Nothing to do. Normally used to indicate a dependency
on a certain symbol (like for exception handling under EABI). */ on a certain symbol (like for exception handling under EABI). */
return; return;
case R_ARM_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;
default: default:
fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned)addr, ptr, (unsigned)val); type, (unsigned)addr, ptr, (unsigned)val);
......
...@@ -240,6 +240,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t ...@@ -240,6 +240,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
#endif #endif
write64le(ptr, val - rel->r_addend); write64le(ptr, val - rel->r_addend);
return; return;
case R_AARCH64_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;
default: default:
fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned)addr, ptr, (unsigned)val); type, (unsigned)addr, ptr, (unsigned)val);
......
...@@ -226,6 +226,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t ...@@ -226,6 +226,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
write16le(ptr, read16le(ptr) + val - addr); write16le(ptr, read16le(ptr) + val - addr);
return; return;
case R_386_RELATIVE: case R_386_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */ /* do nothing */
return; return;
case R_386_COPY: case R_386_COPY:
......
...@@ -182,9 +182,9 @@ static void print_search_dirs(TCCState *s) ...@@ -182,9 +182,9 @@ static void print_search_dirs(TCCState *s)
/* print_dirs("programs", NULL, 0); */ /* print_dirs("programs", NULL, 0); */
print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths); print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
print_dirs("libraries", s->library_paths, s->nb_library_paths); print_dirs("libraries", s->library_paths, s->nb_library_paths);
printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
#ifndef TCC_TARGET_PE #ifndef TCC_TARGET_PE
print_dirs("crt", s->crt_paths, s->nb_crt_paths); print_dirs("crt", s->crt_paths, s->nb_crt_paths);
printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s)); printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
#endif #endif
} }
......
...@@ -489,14 +489,6 @@ typedef struct Sym { ...@@ -489,14 +489,6 @@ typedef struct Sym {
} Sym; } Sym;
/* section definition */ /* section definition */
/* XXX: use directly ELF structure for parameters ? */
/* special flag to indicate that the section should not be linked to
the other ones */
#define SHF_PRIVATE 0x80000000
/* special flag, too */
#define SECTION_ABS ((void *)1)
typedef struct Section { typedef struct Section {
unsigned long data_offset; /* current data offset */ unsigned long data_offset; /* current data offset */
unsigned char *data; /* section data */ unsigned char *data; /* section data */
...@@ -795,15 +787,13 @@ struct TCCState { ...@@ -795,15 +787,13 @@ struct TCCState {
struct sym_attr *sym_attrs; struct sym_attr *sym_attrs;
int nb_sym_attrs; int nb_sym_attrs;
/* tiny assembler state */
ElfSym esym_dot;
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
/* PE info */ /* PE info */
int pe_subsystem; int pe_subsystem;
unsigned pe_characteristics; unsigned pe_characteristics;
unsigned pe_file_align; unsigned pe_file_align;
unsigned pe_stack_size; unsigned pe_stack_size;
addr_t pe_imagebase;
# ifdef TCC_TARGET_X86_64 # ifdef TCC_TARGET_X86_64
Section *uw_pdata; Section *uw_pdata;
int uw_sym; int uw_sym;
...@@ -1390,7 +1380,7 @@ ST_DATA Section *lbounds_section; /* contains local data bound description */ ...@@ -1390,7 +1380,7 @@ ST_DATA Section *lbounds_section; /* contains local data bound description */
ST_FUNC void tccelf_bounds_new(TCCState *s); ST_FUNC void tccelf_bounds_new(TCCState *s);
#endif #endif
/* symbol sections */ /* symbol sections */
ST_DATA Section *symtab_section, *strtab_section; ST_DATA Section *symtab_section;
/* debug sections */ /* debug sections */
ST_DATA Section *stab_section, *stabstr_section; ST_DATA Section *stab_section, *stabstr_section;
...@@ -1408,7 +1398,7 @@ ST_FUNC void section_reserve(Section *sec, unsigned long size); ...@@ -1408,7 +1398,7 @@ ST_FUNC void section_reserve(Section *sec, unsigned long size);
ST_FUNC Section *find_section(TCCState *s1, const char *name); ST_FUNC Section *find_section(TCCState *s1, const char *name);
ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore); ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size); ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
#if PTR_SIZE == 4 #if PTR_SIZE == 4
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
...@@ -1551,6 +1541,9 @@ ST_FUNC void gen_bounded_ptr_deref(void); ...@@ -1551,6 +1541,9 @@ ST_FUNC void gen_bounded_ptr_deref(void);
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
ST_FUNC void gen_opl(int op); ST_FUNC void gen_opl(int op);
#ifdef TCC_TARGET_PE
ST_FUNC void gen_vla_result(int addr);
#endif
#endif #endif
/* ------------ arm-gen.c ------------ */ /* ------------ arm-gen.c ------------ */
......
...@@ -32,7 +32,8 @@ ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) ...@@ -32,7 +32,8 @@ ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
} }
static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global); static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
static Sym sym_dot; static Sym* asm_new_label(TCCState *s1, int label, int is_local);
static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
static Sym *asm_label_find(int v) static Sym *asm_label_find(int v)
{ {
...@@ -73,6 +74,16 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym) ...@@ -73,6 +74,16 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
return sym; return sym;
} }
static Sym* asm_section_sym(TCCState *s1, Section *sec)
{
char buf[100];
int label = tok_alloc(buf,
snprintf(buf, sizeof buf, "L.%s", sec->name)
)->tok;
Sym *sym = asm_label_find(label);
return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
}
/* We do not use the C expression parser to handle symbols. Maybe the /* We do not use the C expression parser to handle symbols. Maybe the
C expression parser could be tweaked to do so. */ C expression parser could be tweaked to do so. */
...@@ -145,13 +156,9 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) ...@@ -145,13 +156,9 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
skip(')'); skip(')');
break; break;
case '.': case '.':
pe->v = 0; pe->v = ind;
pe->sym = &sym_dot; pe->sym = asm_section_sym(s1, cur_text_section);
pe->pcrel = 0; pe->pcrel = 0;
sym_dot.type.t = VT_ASM | VT_STATIC;
sym_dot.c = -1;
tcc_state->esym_dot.st_shndx = cur_text_section->sh_num;
tcc_state->esym_dot.st_value = ind;
next(); next();
break; break;
default: default:
...@@ -368,29 +375,26 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, ...@@ -368,29 +375,26 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
/* A VT_EXTERN symbol, even if it has a section is considered /* A VT_EXTERN symbol, even if it has a section is considered
overridable. This is how we "define" .set targets. Real overridable. This is how we "define" .set targets. Real
definitions won't have VT_EXTERN set. */ definitions won't have VT_EXTERN set. */
if (esym && esym->st_shndx != SHN_UNDEF && !(sym->type.t & VT_EXTERN)) { if (esym && esym->st_shndx != SHN_UNDEF) {
/* the label is already defined */ /* the label is already defined */
if (is_local != 1) { if (IS_ASM_SYM(sym)
tcc_error("assembler label '%s' already defined", && (is_local == 1 || (sym->type.t & VT_EXTERN)))
get_tok_str(label, NULL));
} else {
/* redefinition of local labels is possible */
goto new_label; goto new_label;
} if (!(sym->type.t & VT_EXTERN))
tcc_error("assembler label '%s' already defined",
get_tok_str(label, NULL));
} }
} else { } else {
new_label: new_label:
sym = asm_label_push(label); sym = asm_label_push(label);
} }
if (!sym->c) if (!sym->c)
put_extern_sym2(sym, NULL, 0, 0, 0); put_extern_sym2(sym, SHN_UNDEF, 0, 0, 0);
esym = elfsym(sym); esym = elfsym(sym);
esym->st_shndx = sh_num; esym->st_shndx = sh_num;
esym->st_value = value; esym->st_value = value;
if (is_local != 2) if (is_local != 2)
sym->type.t &= ~VT_EXTERN; sym->type.t &= ~VT_EXTERN;
return sym; return sym;
} }
......
...@@ -38,13 +38,18 @@ ST_DATA Section *bounds_section; /* contains global data bound description */ ...@@ -38,13 +38,18 @@ ST_DATA Section *bounds_section; /* contains global data bound description */
ST_DATA Section *lbounds_section; /* contains local data bound description */ ST_DATA Section *lbounds_section; /* contains local data bound description */
#endif #endif
/* symbol sections */ /* symbol sections */
ST_DATA Section *symtab_section, *strtab_section; ST_DATA Section *symtab_section;
/* debug sections */ /* debug sections */
ST_DATA Section *stab_section, *stabstr_section; ST_DATA Section *stab_section, *stabstr_section;
/* XXX: avoid static variable */ /* XXX: avoid static variable */
static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */ static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
/* special flag to indicate that the section should not be linked to the other ones */
#define SHF_PRIVATE 0x80000000
/* section is dynsymtab_section */
#define SHF_DYNSYM 0x40000000
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
ST_FUNC void tccelf_new(TCCState *s) ST_FUNC void tccelf_new(TCCState *s)
...@@ -63,11 +68,10 @@ ST_FUNC void tccelf_new(TCCState *s) ...@@ -63,11 +68,10 @@ ST_FUNC void tccelf_new(TCCState *s)
symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
".strtab", ".strtab",
".hashtab", SHF_PRIVATE); ".hashtab", SHF_PRIVATE);
strtab_section = symtab_section->link;
s->symtab = symtab_section; s->symtab = symtab_section;
/* private symbol table for dynamic symbols */ /* private symbol table for dynamic symbols */
s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
".dynstrtab", ".dynstrtab",
".dynhashtab", SHF_PRIVATE); ".dynhashtab", SHF_PRIVATE);
get_sym_attr(s, 0, 1); get_sym_attr(s, 0, 1);
...@@ -128,6 +132,8 @@ ST_FUNC void tccelf_delete(TCCState *s1) ...@@ -128,6 +132,8 @@ ST_FUNC void tccelf_delete(TCCState *s1)
/* free loaded dlls array */ /* free loaded dlls array */
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
tcc_free(s1->sym_attrs); tcc_free(s1->sym_attrs);
symtab_section = NULL; /* for tccrun.c:rt_printline() */
} }
/* save section data state */ /* save section data state */
...@@ -536,7 +542,7 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, ...@@ -536,7 +542,7 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
goto do_patch; goto do_patch;
} else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) { } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
/* data symbol keeps precedence over common/bss */ /* data symbol keeps precedence over common/bss */
} else if (s == tcc_state->dynsymtab_section) { } else if (s->sh_flags & SHF_DYNSYM) {
/* we accept that two DLL define the same symbol */ /* we accept that two DLL define the same symbol */
} else if (esym->st_other & ST_ASM_SET) { } else if (esym->st_other & ST_ASM_SET) {
/* If the existing symbol came from an asm .set /* If the existing symbol came from an asm .set
...@@ -779,7 +785,7 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) ...@@ -779,7 +785,7 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
for_each_elem(symtab, 1, sym, ElfW(Sym)) { for_each_elem(symtab, 1, sym, ElfW(Sym)) {
sh_num = sym->st_shndx; sh_num = sym->st_shndx;
if (sh_num == SHN_UNDEF) { if (sh_num == SHN_UNDEF) {
name = (char *) strtab_section->data + sym->st_name; name = (char *) s1->symtab->link->data + sym->st_name;
/* Use ld.so to resolve symbol for us (for tcc -run) */ /* Use ld.so to resolve symbol for us (for tcc -run) */
if (do_resolve) { if (do_resolve) {
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
......
...@@ -285,10 +285,7 @@ ST_FUNC ElfSym *elfsym(Sym *s) ...@@ -285,10 +285,7 @@ ST_FUNC ElfSym *elfsym(Sym *s)
{ {
if (!s || !s->c) if (!s || !s->c)
return NULL; return NULL;
if (s->c == -1) return &((ElfSym *)symtab_section->data)[s->c];
return &tcc_state->esym_dot;
else
return &((ElfSym *)symtab_section->data)[s->c];
} }
/* apply storage attributes to Elf symbol */ /* apply storage attributes to Elf symbol */
...@@ -338,11 +335,11 @@ ST_FUNC void update_storage(Sym *sym) ...@@ -338,11 +335,11 @@ ST_FUNC void update_storage(Sym *sym)
/* update sym->c so that it points to an external symbol in section /* update sym->c so that it points to an external symbol in section
'section' with value 'value' */ 'section' with value 'value' */
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
addr_t value, unsigned long size, addr_t value, unsigned long size,
int can_add_underscore) int can_add_underscore)
{ {
int sym_type, sym_bind, sh_num, info, other, t; int sym_type, sym_bind, info, other, t;
ElfSym *esym; ElfSym *esym;
const char *name; const char *name;
char buf1[256]; char buf1[256];
...@@ -350,13 +347,6 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, ...@@ -350,13 +347,6 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
char buf[32]; char buf[32];
#endif #endif
if (section == NULL)
sh_num = SHN_UNDEF;
else if (section == SECTION_ABS)
sh_num = SHN_ABS;
else
sh_num = section->sh_num;
if (!sym->c) { if (!sym->c) {
name = get_tok_str(sym->v, NULL); name = get_tok_str(sym->v, NULL);
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
...@@ -431,7 +421,8 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, ...@@ -431,7 +421,8 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
ST_FUNC void put_extern_sym(Sym *sym, Section *section, ST_FUNC void put_extern_sym(Sym *sym, Section *section,
addr_t value, unsigned long size) addr_t value, unsigned long size)
{ {
put_extern_sym2(sym, section, value, size, 1); int sh_num = section ? section->sh_num : SHN_UNDEF;
put_extern_sym2(sym, sh_num, value, size, 1);
} }
/* add a new relocation entry to symbol 'sym' in section 's' */ /* add a new relocation entry to symbol 'sym' in section 's' */
...@@ -848,6 +839,7 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) ...@@ -848,6 +839,7 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
} else if (IS_ASM_SYM(s)) { } else if (IS_ASM_SYM(s)) {
s->type.t = type->t | (s->type.t & VT_EXTERN); s->type.t = type->t | (s->type.t & VT_EXTERN);
s->type.ref = type->ref; s->type.ref = type->ref;
update_storage(s);
} }
return s; return s;
} }
...@@ -862,9 +854,12 @@ static void patch_type(Sym *sym, CType *type) ...@@ -862,9 +854,12 @@ static void patch_type(Sym *sym, CType *type)
} }
if (IS_ASM_SYM(sym)) { if (IS_ASM_SYM(sym)) {
sym->type = *type; /* stay static if both are static */
sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
sym->type.ref = type->ref;
}
} else if (!is_compatible_types(&sym->type, type)) { if (!is_compatible_types(&sym->type, type)) {
tcc_error("incompatible types for redefinition of '%s'", tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(sym->v, NULL)); get_tok_str(sym->v, NULL));
...@@ -876,10 +871,11 @@ static void patch_type(Sym *sym, CType *type) ...@@ -876,10 +871,11 @@ static void patch_type(Sym *sym, CType *type)
get_tok_str(sym->v, NULL)); get_tok_str(sym->v, NULL));
if (0 == (type->t & VT_EXTERN)) { if (0 == (type->t & VT_EXTERN)) {
/* put complete type */ /* put complete type, use static from prototype */
sym->type = *type; sym->type.t = (type->t & ~VT_STATIC) | static_proto;
/* use static from prototype */ if (type->t & VT_INLINE)
sym->type.t |= static_proto; sym->type.t = type->t;
sym->type.ref = type->ref;
} }
} else { } else {
...@@ -6570,8 +6566,10 @@ static void init_putv(CType *type, Section *sec, unsigned long c) ...@@ -6570,8 +6566,10 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
memcpy(ptr, &vtop->c.ld, 10); memcpy(ptr, &vtop->c.ld, 10);
#ifdef __TINYC__ #ifdef __TINYC__
else if (sizeof (long double) == sizeof (double)) else if (sizeof (long double) == sizeof (double))
__asm__("fldl %1\nfstpt %0\n" : "=m" (ptr) : "m" (vtop->c.ld)); __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
#endif #endif
else if (vtop->c.ld == 0.0)
;
else else
#endif #endif
if (sizeof(long double) == LDOUBLE_SIZE) if (sizeof(long double) == LDOUBLE_SIZE)
...@@ -7019,6 +7017,11 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, ...@@ -7019,6 +7017,11 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
vla_runtime_type_size(type, &a); vla_runtime_type_size(type, &a);
gen_vla_alloc(type, a); gen_vla_alloc(type, a);
#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
/* on _WIN64, because of the function args scratch area, the
result of alloca differs from RSP and is returned in RAX. */
gen_vla_result(addr), addr = (loc -= PTR_SIZE);
#endif
gen_vla_sp_save(addr); gen_vla_sp_save(addr);
vla_sp_loc = addr; vla_sp_loc = addr;
vlas_in_scope++; vlas_in_scope++;
...@@ -7337,18 +7340,16 @@ found: ...@@ -7337,18 +7340,16 @@ found:
type.t |= VT_EXTERN; type.t |= VT_EXTERN;
sym = external_sym(v, &type, r, &ad); sym = external_sym(v, &type, r, &ad);
if (ad.alias_target) { if (ad.alias_target) {
Section tsec;
ElfSym *esym; ElfSym *esym;
Sym *alias_target; Sym *alias_target;
alias_target = sym_find(ad.alias_target); alias_target = sym_find(ad.alias_target);
esym = elfsym(alias_target); esym = elfsym(alias_target);
if (!esym)