mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-27 06:10:06 +08:00
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:
parent
2b155a8c16
commit
8f6fcb709a
4
tcc.c
4
tcc.c
@ -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
|
||||
|
9
tccelf.c
9
tccelf.c
@ -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
|
||||
|
19
tccgen.c
19
tccgen.c
@ -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);
|
||||
|
44
tccrun.c
44
tccrun.c
@ -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;
|
||||
|
@ -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
|
||||
|
@ -21,3 +21,6 @@ size of data/text:
|
||||
[test_data_suppression_on]
|
||||
size of data/text:
|
||||
zero/zero
|
||||
|
||||
[test_static_data]
|
||||
a = 1
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
11
x86_64-gen.c
11
x86_64-gen.c
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user