misc fixes

misc fixes including:
- tcc.c: fix "tcc -vv" for libtcc1.a on win32/PE
- tccelf.c: fix a crash when GOT has no relocs (witn -nostdlib)
- tccelf.c: fix stab linkage for zero n_strx
- tccgen.c: fix stdcall decoration for array parameters
    int __stdcall func(char buf[10]) is _func@4 (was _func@12)
- tccgen.c: fix static variables with nocode/nodata_wanted
    see tests2/96_nodata_wanted.c
- tccrun.c: align sections using sh_addralign (for reliable function_alignment)
- tests2/Makefile sort 100 after 99
- win32/include/sys/stat.h fix _stat and _wstat
- x86_64-gen.c: win64/gfunc_call: fix a bug with xmmN register args
    previously overwrote valid other xmmN registers eventually
This commit is contained in:
grischka 2018-05-31 23:51:51 +02:00
parent 2b155a8c16
commit 8f6fcb709a
9 changed files with 73 additions and 49 deletions

4
tcc.c
View File

@ -182,8 +182,10 @@ static void print_search_dirs(TCCState *s)
/* print_dirs("programs", NULL, 0); */
print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
print_dirs("libraries", s->library_paths, s->nb_library_paths);
#ifdef TCC_TARGET_PE
printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", s->tcc_lib_path);
#else
printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
#ifndef TCC_TARGET_PE
print_dirs("crt", s->crt_paths, s->nb_crt_paths);
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
#endif

View File

@ -1364,6 +1364,8 @@ ST_FUNC void fill_got(TCCState *s1)
static void fill_local_got_entries(TCCState *s1)
{
ElfW_Rel *rel;
if (!s1->got->reloc)
return;
for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
int sym_index = ELFW(R_SYM) (rel->r_info);
@ -2443,8 +2445,11 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
b = (Stab_Sym *)(s->data + s->data_offset);
o = sm_table[stabstr_index].offset;
while (a < b)
a->n_strx += o, a++;
while (a < b) {
if (a->n_strx)
a->n_strx += o;
a++;
}
}
/* second short pass to update sh_link and sh_info fields of new

View File

@ -4294,7 +4294,6 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
if ((pt.t & VT_BTYPE) == VT_VOID)
tcc_error("parameter declared as void");
arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
} else {
n = tok;
if (n < TOK_UIDENT)
@ -4303,6 +4302,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
next();
}
convert_parameter_type(&pt);
arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
s = sym_push(n | SYM_FIELD, &pt, 0, 0);
*plast = s;
plast = &s->next;
@ -6856,11 +6856,16 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
Sym *sym = NULL;
int saved_nocode_wanted = nocode_wanted;
#ifdef CONFIG_TCC_BCHECK
int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
int bcheck;
#endif
if (type->t & VT_STATIC)
nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000;
/* Always allocate static or global variables */
if (v && (r & VT_VALMASK) == VT_CONST)
nocode_wanted |= 0x80000000;
#ifdef CONFIG_TCC_BCHECK
bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
#endif
flexible_array = NULL;
if ((type->t & VT_BTYPE) == VT_STRUCT) {
@ -6926,7 +6931,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
align = 1;
}
if (NODATA_WANTED)
if (!v && NODATA_WANTED)
size = 0, align = 1;
if ((r & VT_VALMASK) == VT_LOCAL) {
@ -7088,9 +7093,7 @@ static void gen_function(Sym *sym)
if (sym->a.aligned) {
size_t newoff = section_add(cur_text_section, 0,
1 << (sym->a.aligned - 1));
if (ind != newoff)
gen_fill_nops(newoff - ind);
ind = newoff;
gen_fill_nops(newoff - ind);
}
/* NOTE: we patch the symbol size later */
put_extern_sym(sym, cur_text_section, ind, 0);

View File

@ -169,9 +169,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
}
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
/* To avoid that x86 processors would reload cached instructions
each time when data is written in the near, we need to make
sure that code and data do not share the same 64 byte unit */
#define RUN_SECTION_ALIGNMENT 63
#else
#define RUN_SECTION_ALIGNMENT 15
#define RUN_SECTION_ALIGNMENT 0
#endif
/* relocate code. Return -1 on error, required size if ptr is NULL,
@ -179,8 +182,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
{
Section *s;
unsigned offset, length, fill, i, k;
addr_t mem;
unsigned offset, length, align, max_align, i, k, f;
addr_t mem, addr;
if (NULL == ptr) {
s1->nb_errors = 0;
@ -195,39 +198,32 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
return -1;
}
offset = 0, mem = (addr_t)ptr;
fill = -mem & RUN_SECTION_ALIGNMENT;
offset = max_align = 0, mem = (addr_t)ptr;
#ifdef _WIN64
offset += sizeof (void*);
offset += sizeof (void*); /* space for function_table pointer */
#endif
for (k = 0; k < 2; ++k) {
f = 0, addr = k ? mem : mem + ptr_diff;
for(i = 1; i < s1->nb_sections; i++) {
s = s1->sections[i];
if (0 == (s->sh_flags & SHF_ALLOC))
continue;
if (k != !(s->sh_flags & SHF_EXECINSTR))
continue;
offset += fill;
if (!mem)
s->sh_addr = 0;
else if (s->sh_flags & SHF_EXECINSTR)
s->sh_addr = mem + offset + ptr_diff;
else
s->sh_addr = mem + offset;
align = s->sh_addralign - 1;
if (++f == 1 && align < RUN_SECTION_ALIGNMENT)
align = RUN_SECTION_ALIGNMENT;
if (max_align < align)
max_align = align;
offset += -(addr + offset) & align;
s->sh_addr = mem ? addr + offset : 0;
offset += s->data_offset;
#if 0
if (mem)
printf("%-16s +%02lx %p %04x\n",
s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset);
printf("%-16s %p len %04x align %2d\n",
s->name, (void*)s->sh_addr, (unsigned)s->data_offset, align + 1);
#endif
offset += s->data_offset;
fill = -(mem + offset) & 15;
}
#if RUN_SECTION_ALIGNMENT > 15
/* To avoid that x86 processors would reload cached instructions each time
when data is written in the near, we need to make sure that code and data
do not share the same 64 byte unit */
fill = -(mem + offset) & RUN_SECTION_ALIGNMENT;
#endif
}
/* relocate symbols */
@ -236,7 +232,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
return -1;
if (0 == mem)
return offset + RUN_SECTION_ALIGNMENT;
return offset + max_align;
#ifdef TCC_TARGET_PE
s1->pe_imagebase = mem;

View File

@ -55,11 +55,10 @@ te0:;
static char ds1 = 0;
ts1:;
if (!SKIP) {
static void *p = (void*)&main;
static char cc[] = "static string";
static double d = 8.0;
static struct __attribute__((packed)) {
void *p = (void*)&main;
char cc[] = "static string";
double d = 8.0;
struct __attribute__((packed)) {
unsigned x : 12;
unsigned char y : 7;
unsigned z : 28, a: 4, b: 5;
@ -81,4 +80,19 @@ te1:;
/*printf("# %d/%d\n", dl, tl);*/
}
#elif defined test_static_data
#include <stdio.h>
int main(int argc, char **argv)
{
goto there;
if (0) {
static int a = 1;
printf("hello\n"); /* the "hello\n" string is still suppressed */
there:
printf("a = %d\n", a);
}
return 0;
}
#endif

View File

@ -21,3 +21,6 @@ size of data/text:
[test_data_suppression_on]
size of data/text:
zero/zero
[test_static_data]
a = 1

View File

@ -3,7 +3,9 @@ include $(TOP)/Makefile
SRC = $(TOPSRC)/tests/tests2
VPATH = $(SRC)
TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c))))
TESTS = $(patsubst %.c,%.test,\
$(sort $(notdir $(wildcard $(SRC)/??_*.c)))\
$(sort $(notdir $(wildcard $(SRC)/???_*.c))))
# some tests do not pass on all platforms, remove them for now
SKIP = 34_array_assignment.test # array assignment is not in C standard

View File

@ -81,9 +81,9 @@ extern "C" {
#else
#define _fstat _fstat64i32
#define _fstati64 _fstat64
#define _stat _stat64i32
#define _stat _stat64
#define _stati64 _stat64
#define _wstat _wstat64i32
#define _wstat _wstat64
#define _wstati64 _wstat64
#endif

View File

@ -877,19 +877,18 @@ void gfunc_call(int nb_args)
if (is_sse_float(vtop->type.t)) {
if (tcc_state->nosse)
tcc_error("SSE disabled");
gv(RC_XMM0); /* only use one float register */
if (arg >= REGN) {
gv(RC_XMM0);
/* movq %xmm0, j*8(%rsp) */
gen_offs_sp(0xd60f66, 0x100, arg*8);
} else {
/* movaps %xmm0, %xmmN */
o(0x280f);
o(0xc0 + (arg << 3));
/* Load directly to xmmN register */
gv(RC_XMM0 << arg);
d = arg_prepare_reg(arg);
/* mov %xmm0, %rxx */
/* mov %xmmN, %rxx */
o(0x66);
orex(1,d,0, 0x7e0f);
o(0xc0 + REG_VALUE(d));
o(0xc0 + arg*8 + REG_VALUE(d));
}
} else {
if (bt == VT_STRUCT) {