mirror of
https://github.com/frida/tinycc
synced 2024-11-27 10:09:42 +03:00
some smaller fixes
- libtcc.c/tccpp.c: fix -U option for multiple input files - libtcc: remove decl of tcc_add_crt() for PE - tcc.h: define __i386__ and __x86_64__ for msvc - tcc.h: undef __attribute__ for __TINYC__ on gnu/linux platforms - tccelf.c: disable prepare_dynamic_rel unless x86/x64 - tccpe.c: construct rather than predefine PE section flags - tccpp.c: (alt.) fix access of dead stack variable after error/longjmp - x86_64-gen.c: fix func_alloca chain for nocode_wanted - tccpp.c/tccgen.c: improve file:line info for inline functions - winapi/winnt.h: correct position for DECLSPEC_ALIGN attribute - win32/lib/crt: simplify top exception handler (needed for signal) - arm64-gen.c: remove dprintf left from VT_CMP commit - tccgen.c: limit binary scan with gcase to > 8 (= smaller code) - tccgen.c: call save_regs(4) in gen_opl for cmp-ops (see test in tcctest.c)
This commit is contained in:
parent
4bb5bc4401
commit
ce1ef5b8fc
11
arm64-gen.c
11
arm64-gen.c
@ -91,9 +91,6 @@ static uint32_t fltr(int r)
|
||||
return r - TREG_F(0);
|
||||
}
|
||||
|
||||
#define dprintf(x) ((void)(tcc_state->verbose == 2 && printf x))
|
||||
//#define dprintf(x)
|
||||
|
||||
// Add an instruction to text section:
|
||||
ST_FUNC void o(unsigned int c)
|
||||
{
|
||||
@ -103,7 +100,6 @@ ST_FUNC void o(unsigned int c)
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(cur_text_section, ind1);
|
||||
write32le(cur_text_section->data + ind, c);
|
||||
dprintf(("o %04x : %08x\n", ind, c)); //gr
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
@ -236,7 +232,6 @@ ST_FUNC void gsym_addr(int t_, int a_)
|
||||
tcc_error("branch out of range");
|
||||
write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
|
||||
0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b
|
||||
dprintf((". gsym TARG=%04x ADDR=%04x\n", t, a)); //gr
|
||||
t = next;
|
||||
}
|
||||
}
|
||||
@ -1296,7 +1291,6 @@ ST_FUNC void gen_fill_nops(int bytes)
|
||||
ST_FUNC int gjmp(int t)
|
||||
{
|
||||
int r = ind;
|
||||
dprintf((". gjmp T=%04x\n", t)); //gr
|
||||
if (nocode_wanted)
|
||||
return t;
|
||||
o(t);
|
||||
@ -1308,7 +1302,6 @@ ST_FUNC void gjmp_addr(int a)
|
||||
{
|
||||
assert(a - ind + 0x8000000 < 0x10000000);
|
||||
o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));
|
||||
dprintf((". gjmp_addr T=%04x\n", a)); //gr
|
||||
}
|
||||
|
||||
ST_FUNC int gjmp_append(int n, int t)
|
||||
@ -1330,7 +1323,6 @@ void arm64_vset_VT_CMP(int op)
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
vtop->cmp_r = vtop->r;
|
||||
vset_VT_CMP(0x80);
|
||||
dprintf((". set VT_CMP OP(%s) R=%x\n", get_tok_str(op, 0), vtop->cmp_r));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1339,7 +1331,6 @@ static void arm64_gen_opil(int op, uint32_t l);
|
||||
static void arm64_load_cmp(int r, SValue *sv)
|
||||
{
|
||||
sv->r = sv->cmp_r;
|
||||
dprintf((". load VT_CMP OP(%x), R=%x/%x\n", (int)sv->c.i, sv->r, r));
|
||||
if (sv->c.i & 1) {
|
||||
vpushi(1);
|
||||
arm64_gen_opil('^', 0);
|
||||
@ -1348,7 +1339,6 @@ static void arm64_load_cmp(int r, SValue *sv)
|
||||
load(r, sv);
|
||||
sv->r = r;
|
||||
}
|
||||
dprintf((". load VT_CMP done\n")); //gr
|
||||
}
|
||||
|
||||
ST_FUNC int gjmp_cond(int op, int t)
|
||||
@ -1357,7 +1347,6 @@ ST_FUNC int gjmp_cond(int op, int t)
|
||||
|
||||
int inv = op & 1;
|
||||
vtop->r = vtop->cmp_r;
|
||||
dprintf((". gjmp_cond OP(%x) R=%x T=%04x\n", op, vtop->r, t)); //gr
|
||||
|
||||
if (bt == VT_LDOUBLE) {
|
||||
uint32_t a, b, f = fltr(gv(RC_FLOAT));
|
||||
|
8
libtcc.c
8
libtcc.c
@ -700,9 +700,11 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
|
||||
Sym *s;
|
||||
ts = tok_alloc(sym, strlen(sym));
|
||||
s = define_find(ts->tok);
|
||||
/* undefine symbol by putting an invalid name */
|
||||
if (s)
|
||||
if (s) {
|
||||
define_undef(s);
|
||||
tok_str_free_str(s->d);
|
||||
s->d = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup all static data used during compilation */
|
||||
@ -1118,6 +1120,7 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
|
||||
s->library_paths, s->nb_library_paths);
|
||||
}
|
||||
|
||||
#ifndef TCC_TARGET_PE
|
||||
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
|
||||
{
|
||||
if (-1 == tcc_add_library_internal(s, "%s/%s",
|
||||
@ -1125,6 +1128,7 @@ ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
|
||||
tcc_error_noabort("file '%s' not found", filename);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* the library name is the same as the argument of the '-l' option */
|
||||
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
|
||||
|
19
tcc.h
19
tcc.h
@ -73,6 +73,12 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
# pragma warning (disable : 4018) // signed/unsigned mismatch
|
||||
# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
# define ssize_t intptr_t
|
||||
# ifdef _X86_
|
||||
# define __i386__ 1
|
||||
# endif
|
||||
# ifdef _AMD64_
|
||||
# define __x86_64__ 1
|
||||
# endif
|
||||
# endif
|
||||
# undef CONFIG_TCC_STATIC
|
||||
#endif
|
||||
@ -97,6 +103,11 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
# define ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
/* gnu headers use to #define __attribute__ to empty for non-gcc compilers */
|
||||
#ifdef __TINYC__
|
||||
# undef __attribute__
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define IS_DIRSEP(c) (c == '/' || c == '\\')
|
||||
# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
|
||||
@ -133,7 +144,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
|
||||
!defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \
|
||||
!defined(TCC_TARGET_X86_64)
|
||||
# if defined __x86_64__ || defined _AMD64_
|
||||
# if defined __x86_64__
|
||||
# define TCC_TARGET_X86_64
|
||||
# elif defined __arm__
|
||||
# define TCC_TARGET_ARM
|
||||
@ -151,9 +162,9 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
|
||||
/* only native compiler supports -run */
|
||||
#if defined _WIN32 == defined TCC_TARGET_PE
|
||||
# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386
|
||||
# if defined __i386__ && defined TCC_TARGET_I386
|
||||
# define TCC_IS_NATIVE
|
||||
# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64
|
||||
# elif defined __x86_64__ && defined TCC_TARGET_X86_64
|
||||
# define TCC_IS_NATIVE
|
||||
# elif defined __arm__ && defined TCC_TARGET_ARM
|
||||
# define TCC_IS_NATIVE
|
||||
@ -1179,7 +1190,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
#define AFF_BINTYPE_C67 4
|
||||
|
||||
|
||||
#ifndef TCC_TARGET_PE
|
||||
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
|
||||
#endif
|
||||
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
|
||||
ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
|
||||
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
|
||||
|
14
tccelf.c
14
tccelf.c
@ -171,7 +171,7 @@ ST_FUNC void tccelf_end_file(TCCState *s1)
|
||||
&& ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
|
||||
sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
|
||||
tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
|
||||
sym->st_other, sym->st_shndx, s->link->data + sym->st_name);
|
||||
sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
|
||||
}
|
||||
/* now update relocations */
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
@ -865,17 +865,13 @@ static void relocate_rel(TCCState *s1, Section *sr)
|
||||
their space */
|
||||
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||
{
|
||||
int count = 0;
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
|
||||
ElfW_Rel *rel;
|
||||
int type, count;
|
||||
|
||||
count = 0;
|
||||
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
#endif
|
||||
type = ELFW(R_TYPE)(rel->r_info);
|
||||
int type = ELFW(R_TYPE)(rel->r_info);
|
||||
switch(type) {
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
|
||||
#if defined(TCC_TARGET_I386)
|
||||
case R_386_32:
|
||||
if (!get_sym_attr(s1, sym_index, 0)->dyn_index
|
||||
@ -899,7 +895,6 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||
if (get_sym_attr(s1, sym_index, 0)->dyn_index)
|
||||
count++;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -909,6 +904,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||
sr->sh_flags |= SHF_ALLOC;
|
||||
sr->sh_size = count * sizeof(ElfW_Rel);
|
||||
}
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
|
12
tccgen.c
12
tccgen.c
@ -1990,6 +1990,7 @@ static void gen_opl(int op)
|
||||
vtop[-1] = vtop[-2];
|
||||
vtop[-2] = tmp;
|
||||
/* stack: L1 L2 H1 H2 */
|
||||
save_regs(4);
|
||||
/* compare high */
|
||||
op1 = op;
|
||||
/* when values are equal, we need to compare low words. since
|
||||
@ -2205,7 +2206,7 @@ static void gen_opif(int op)
|
||||
{
|
||||
int c1, c2;
|
||||
SValue *v1, *v2;
|
||||
#if defined _MSC_VER && defined _AMD64_
|
||||
#if defined _MSC_VER && defined __x86_64__
|
||||
/* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
|
||||
volatile
|
||||
#endif
|
||||
@ -4497,6 +4498,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
|
||||
if (n < TOK_UIDENT)
|
||||
expect("identifier");
|
||||
pt.t = VT_VOID; /* invalid type */
|
||||
pt.ref = NULL;
|
||||
next();
|
||||
}
|
||||
convert_parameter_type(&pt);
|
||||
@ -6113,7 +6115,7 @@ static void gcase(struct case_t **base, int len, int *bsym)
|
||||
struct case_t *p;
|
||||
int e;
|
||||
int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
|
||||
while (len > 4) {
|
||||
while (len > 8) {
|
||||
/* binary search */
|
||||
p = base[len/2];
|
||||
vdup();
|
||||
@ -7538,10 +7540,10 @@ static void gen_function(Sym *sym)
|
||||
static void gen_inline_functions(TCCState *s)
|
||||
{
|
||||
Sym *sym;
|
||||
int inline_generated, i, ln;
|
||||
int inline_generated, i;
|
||||
struct InlineFunc *fn;
|
||||
|
||||
ln = file->line_num;
|
||||
tcc_open_bf(s, ":inline:", 0);
|
||||
/* iterate while inline function are referenced */
|
||||
do {
|
||||
inline_generated = 0;
|
||||
@ -7564,7 +7566,7 @@ static void gen_inline_functions(TCCState *s)
|
||||
}
|
||||
}
|
||||
} while (inline_generated);
|
||||
file->line_num = ln;
|
||||
tcc_close();
|
||||
}
|
||||
|
||||
ST_FUNC void free_inline_functions(TCCState *s)
|
||||
|
54
tccpe.c
54
tccpe.c
@ -231,6 +231,17 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
||||
#define IMAGE_REL_BASED_REL32 7
|
||||
#define IMAGE_REL_BASED_DIR64 10
|
||||
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020
|
||||
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
|
||||
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
|
||||
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||
#define IMAGE_SCN_MEM_SHARED 0x10000000
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
#define IMAGE_SCN_TYPE_NOLOAD 0x00000002
|
||||
#define IMAGE_SCN_LNK_REMOVE 0x00000800
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
@ -279,17 +290,6 @@ struct pe_rsrc_reloc {
|
||||
/* ------------------------------------------------------------- */
|
||||
/* internal temporary structures */
|
||||
|
||||
/*
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020
|
||||
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
|
||||
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
|
||||
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||
#define IMAGE_SCN_MEM_SHARED 0x10000000
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
*/
|
||||
|
||||
enum {
|
||||
sec_text = 0,
|
||||
sec_data ,
|
||||
@ -303,6 +303,7 @@ enum {
|
||||
sec_last
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const DWORD pe_sec_flags[] = {
|
||||
0x60000020, /* ".text" , */
|
||||
0xC0000040, /* ".data" , */
|
||||
@ -314,13 +315,14 @@ static const DWORD pe_sec_flags[] = {
|
||||
0x42000802, /* ".stab" , */
|
||||
0x42000040, /* ".reloc" , */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct section_info {
|
||||
int cls, ord;
|
||||
char name[32];
|
||||
DWORD sh_addr;
|
||||
DWORD sh_size;
|
||||
DWORD sh_flags;
|
||||
DWORD pe_flags;
|
||||
unsigned char *data;
|
||||
DWORD data_size;
|
||||
IMAGE_SECTION_HEADER ish;
|
||||
@ -656,9 +658,6 @@ static int pe_write(struct pe_info *pe)
|
||||
case sec_pdata:
|
||||
pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size);
|
||||
break;
|
||||
|
||||
case sec_stab:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pe->thunk == pe->s1->sections[si->ord]) {
|
||||
@ -676,7 +675,7 @@ static int pe_write(struct pe_info *pe)
|
||||
|
||||
strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
|
||||
|
||||
psh->Characteristics = pe_sec_flags[si->cls];
|
||||
psh->Characteristics = si->pe_flags;
|
||||
psh->VirtualAddress = addr;
|
||||
psh->Misc.VirtualSize = size;
|
||||
pe_header.opthdr.SizeOfImage =
|
||||
@ -1064,15 +1063,15 @@ static int pe_section_class(Section *s)
|
||||
return sec_idata;
|
||||
if (0 == strcmp(name, ".pdata"))
|
||||
return sec_pdata;
|
||||
return sec_other;
|
||||
} else if (type == SHT_NOBITS) {
|
||||
if (flags & SHF_WRITE)
|
||||
return sec_bss;
|
||||
}
|
||||
return sec_other;
|
||||
} else {
|
||||
if (0 == strcmp(name, ".reloc"))
|
||||
return sec_reloc;
|
||||
if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */
|
||||
if (0 == memcmp(name, ".stab", 5))
|
||||
return sec_stab;
|
||||
}
|
||||
return -1;
|
||||
@ -1129,7 +1128,21 @@ static int pe_assign_addresses (struct pe_info *pe)
|
||||
si->cls = c;
|
||||
si->ord = k;
|
||||
si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr);
|
||||
si->sh_flags = s->sh_flags;
|
||||
|
||||
si->pe_flags = IMAGE_SCN_MEM_READ;
|
||||
if (s->sh_flags & SHF_EXECINSTR)
|
||||
si->pe_flags |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;
|
||||
else if (s->sh_type == SHT_NOBITS)
|
||||
si->pe_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
|
||||
else
|
||||
si->pe_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
if (s->sh_flags & SHF_WRITE)
|
||||
si->pe_flags |= IMAGE_SCN_MEM_WRITE;
|
||||
if (0 == (s->sh_flags & SHF_ALLOC)) {
|
||||
si->pe_flags |= IMAGE_SCN_MEM_DISCARDABLE;
|
||||
if (c == sec_stab)
|
||||
si->pe_flags |= 0x802; //IMAGE_SCN_TYPE_NOLOAD|IMAGE_SCN_LNK_REMOVE
|
||||
}
|
||||
|
||||
if (c == sec_data && NULL == pe->thunk)
|
||||
pe->thunk = s;
|
||||
@ -1153,9 +1166,8 @@ static int pe_assign_addresses (struct pe_info *pe)
|
||||
si->sh_size = s->data_offset;
|
||||
++pe->sec_count;
|
||||
}
|
||||
// printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name);
|
||||
//printf("%08x %05x %s %08x\n", si->sh_addr, si->sh_size, si->name, si->pe_flags);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i = 1; i < pe->s1->nb_sections; ++i) {
|
||||
Section *s = pe->s1->sections[i];
|
||||
|
41
tccpp.c
41
tccpp.c
@ -1119,9 +1119,9 @@ ST_FUNC void end_macro(void)
|
||||
macro_stack = str->prev;
|
||||
macro_ptr = str->prev_ptr;
|
||||
file->line_num = str->save_line_num;
|
||||
if (str->alloc == 2) {
|
||||
str->alloc = 3; /* just mark as finished */
|
||||
} else {
|
||||
if (str->alloc != 0) {
|
||||
if (str->alloc == 2)
|
||||
str->str = NULL; /* don't free */
|
||||
tok_str_free(str);
|
||||
}
|
||||
}
|
||||
@ -1345,7 +1345,7 @@ ST_FUNC void free_defines(Sym *b)
|
||||
int v = b->v;
|
||||
if (v >= TOK_IDENT && v < tok_ident) {
|
||||
Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
|
||||
if (!*d)
|
||||
if (!*d && b->d)
|
||||
*d = b;
|
||||
}
|
||||
b = b->prev;
|
||||
@ -1799,9 +1799,9 @@ ST_FUNC void preprocess(int is_bof)
|
||||
|
||||
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
|
||||
tcc_error("#include recursion too deep");
|
||||
/* store current file in stack, but increment stack later below */
|
||||
*s1->include_stack_ptr = file;
|
||||
i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
|
||||
/* push current file on stack */
|
||||
*s1->include_stack_ptr++ = file;
|
||||
i = tok == TOK_INCLUDE_NEXT ? file->include_next_index: 0;
|
||||
n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
|
||||
for (; i < n; ++i) {
|
||||
char buf1[sizeof file->filename];
|
||||
@ -1849,10 +1849,10 @@ ST_FUNC void preprocess(int is_bof)
|
||||
printf("%s: including %s\n", file->prev->filename, file->filename);
|
||||
#endif
|
||||
/* update target deps */
|
||||
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
|
||||
if (s1->gen_deps) {
|
||||
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
|
||||
tcc_strdup(buf1));
|
||||
/* push current file in stack */
|
||||
++s1->include_stack_ptr;
|
||||
}
|
||||
/* add include file debug info */
|
||||
if (s1->do_debug)
|
||||
put_stabs(file->filename, N_BINCL, 0, 0, 0);
|
||||
@ -1862,6 +1862,7 @@ ST_FUNC void preprocess(int is_bof)
|
||||
}
|
||||
tcc_error("include file '%s' not found", buf);
|
||||
include_done:
|
||||
--s1->include_stack_ptr;
|
||||
break;
|
||||
case TOK_IFNDEF:
|
||||
c = 1;
|
||||
@ -3486,14 +3487,14 @@ static void macro_subst(
|
||||
}
|
||||
|
||||
{
|
||||
TokenString str;
|
||||
str.str = (int*)macro_str;
|
||||
begin_macro(&str, 2);
|
||||
TokenString *str = tok_str_alloc();
|
||||
str->str = (int*)macro_str;
|
||||
begin_macro(str, 2);
|
||||
|
||||
tok = t;
|
||||
macro_subst_tok(tok_str, nested_list, s);
|
||||
|
||||
if (str.alloc == 3) {
|
||||
if (macro_stack != str) {
|
||||
/* already finished by reading function macro arguments */
|
||||
break;
|
||||
}
|
||||
@ -3554,7 +3555,7 @@ ST_FUNC void next(void)
|
||||
tokstr_buf.len = 0;
|
||||
macro_subst_tok(&tokstr_buf, &nested_list, s);
|
||||
tok_str_add(&tokstr_buf, 0);
|
||||
begin_macro(&tokstr_buf, 2);
|
||||
begin_macro(&tokstr_buf, 0);
|
||||
goto redo;
|
||||
}
|
||||
}
|
||||
@ -3593,6 +3594,7 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
|
||||
pp_debug_tok = pp_debug_symv = 0;
|
||||
pp_once++;
|
||||
pvtop = vtop = vstack - 1;
|
||||
memset(vtop, 0, sizeof *vtop);
|
||||
s1->pack_stack[0] = 0;
|
||||
s1->pack_stack_ptr = s1->pack_stack;
|
||||
|
||||
@ -3628,13 +3630,8 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
|
||||
/* cleanup from error/setjmp */
|
||||
ST_FUNC void preprocess_end(TCCState *s1)
|
||||
{
|
||||
/* Normally macro_stack is NULL here, except if an
|
||||
error was thrown; then it can point to allocated storage
|
||||
or to some stack variables, but those are unwound via
|
||||
setjmp already, so can't be accessed. Only two choices:
|
||||
either we leak memory or we access invalid memory. The
|
||||
former is the better choice. */
|
||||
macro_stack = NULL;
|
||||
while (macro_stack)
|
||||
end_macro();
|
||||
macro_ptr = NULL;
|
||||
}
|
||||
|
||||
|
@ -2466,6 +2466,11 @@ long long llfunc2(long long x, long long y, int z)
|
||||
return x * y * z;
|
||||
}
|
||||
|
||||
void check_opl_save_regs(char *a, long long b, int c)
|
||||
{
|
||||
*a = b < 0 && !c;
|
||||
}
|
||||
|
||||
void longlong_test(void)
|
||||
{
|
||||
long long a, b, c;
|
||||
@ -2538,6 +2543,11 @@ void longlong_test(void)
|
||||
unsigned long long u = 0x8000000000000001ULL;
|
||||
u = (unsigned)(u + 1);
|
||||
printf("long long u=" ULONG_LONG_FORMAT "\n", u);
|
||||
|
||||
/* was a problem with missing save_regs in gen_opl on 32-bit platforms */
|
||||
char cc = 78;
|
||||
check_opl_save_regs(&cc, -1, 0);
|
||||
printf("check_opl_save_regs: %d\n", cc);
|
||||
}
|
||||
|
||||
void manyarg_test(void)
|
||||
|
@ -76,18 +76,12 @@
|
||||
#define _M_AMD64 100 /* Visual Studio */
|
||||
#define USE_MINGW_SETJMP_TWO_ARGS
|
||||
#define mingw_getsp tinyc_getbp
|
||||
#define __TRY__
|
||||
#else
|
||||
#define __stdcall __attribute__((__stdcall__))
|
||||
#define _X86_ 1
|
||||
#define _M_IX86 300 /* Visual Studio */
|
||||
#define WIN32 1
|
||||
#define _USE_32BIT_TIME_T
|
||||
#ifdef __arm__
|
||||
#define __TRY__
|
||||
#else
|
||||
#define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* in stddef.h */
|
||||
|
@ -1310,7 +1310,7 @@ typedef DWORD LCID;
|
||||
#define INITIAL_MXCSR 0x1f80
|
||||
#define INITIAL_FPCSR 0x027f
|
||||
|
||||
typedef DECLSPEC_ALIGN(16) struct _M128A {
|
||||
typedef struct DECLSPEC_ALIGN(16) _M128A {
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} M128A,*PM128A;
|
||||
@ -1336,7 +1336,7 @@ typedef DWORD LCID;
|
||||
|
||||
#define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32)
|
||||
|
||||
typedef DECLSPEC_ALIGN(16) struct _CONTEXT {
|
||||
typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
|
||||
DWORD64 P1Home;
|
||||
DWORD64 P2Home;
|
||||
DWORD64 P3Home;
|
||||
@ -3150,7 +3150,7 @@ typedef DWORD LCID;
|
||||
DWORD Type;
|
||||
} MEMORY_BASIC_INFORMATION32,*PMEMORY_BASIC_INFORMATION32;
|
||||
|
||||
typedef DECLSPEC_ALIGN(16) struct _MEMORY_BASIC_INFORMATION64 {
|
||||
typedef struct DECLSPEC_ALIGN(16) _MEMORY_BASIC_INFORMATION64 {
|
||||
ULONGLONG BaseAddress;
|
||||
ULONGLONG AllocationBase;
|
||||
DWORD AllocationProtect;
|
||||
@ -4949,7 +4949,7 @@ typedef DWORD LCID;
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef struct _SLIST_ENTRY *PSLIST_ENTRY;
|
||||
typedef DECLSPEC_ALIGN(16) struct _SLIST_ENTRY {
|
||||
typedef struct DECLSPEC_ALIGN(16) _SLIST_ENTRY {
|
||||
PSLIST_ENTRY Next;
|
||||
} SLIST_ENTRY;
|
||||
#else
|
||||
@ -4961,7 +4961,7 @@ typedef DWORD LCID;
|
||||
|
||||
#if defined(_WIN64)
|
||||
|
||||
typedef DECLSPEC_ALIGN(16) struct _SLIST_HEADER {
|
||||
typedef struct DECLSPEC_ALIGN(16) _SLIST_HEADER {
|
||||
ULONGLONG Alignment;
|
||||
ULONGLONG Region;
|
||||
} SLIST_HEADER;
|
||||
|
@ -67,125 +67,3 @@ tinyc_getbp:
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
#ifndef __x86_64__
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
/*
|
||||
int _except_handler3(
|
||||
PEXCEPTION_RECORD exception_record,
|
||||
PEXCEPTION_REGISTRATION registration,
|
||||
PCONTEXT context,
|
||||
PEXCEPTION_REGISTRATION dispatcher
|
||||
);
|
||||
|
||||
int __cdecl _XcptFilter(
|
||||
unsigned long xcptnum,
|
||||
PEXCEPTION_POINTERS pxcptinfoptrs
|
||||
);
|
||||
|
||||
struct _sehrec {
|
||||
void *esp; // 0
|
||||
void *exception_pointers; // 1
|
||||
void *prev; // 2
|
||||
void *handler; // 3
|
||||
void *scopetable; // 4
|
||||
int trylevel; // 5
|
||||
void *ebp // 6
|
||||
};
|
||||
|
||||
// this is what the assembler code below means:
|
||||
__try
|
||||
{
|
||||
// ...
|
||||
}
|
||||
__except (_XcptFilter(GetExceptionCode(), GetExceptionInformation()))
|
||||
{
|
||||
exit(GetExceptionCode());
|
||||
}
|
||||
*/
|
||||
|
||||
.globl _exception_info
|
||||
_exception_info:
|
||||
mov 1*4-24(%ebp),%eax
|
||||
ret
|
||||
|
||||
.globl _exception_code
|
||||
_exception_code:
|
||||
call _exception_info
|
||||
mov (%eax),%eax
|
||||
mov (%eax),%eax
|
||||
ret
|
||||
|
||||
seh_filter:
|
||||
call _exception_info
|
||||
push %eax
|
||||
call _exception_code
|
||||
push %eax
|
||||
call _XcptFilter
|
||||
add $ 8,%esp
|
||||
ret
|
||||
|
||||
seh_except:
|
||||
mov 0*4-24(%ebp),%esp
|
||||
call _exception_code
|
||||
push %eax
|
||||
call _exit
|
||||
|
||||
// msvcrt wants scopetables aligned and in read-only segment (using .text)
|
||||
.align 4
|
||||
seh_scopetable:
|
||||
.long -1
|
||||
.long seh_filter
|
||||
.long seh_except
|
||||
|
||||
seh_handler:
|
||||
jmp _except_handler3
|
||||
|
||||
.globl ___try__
|
||||
___try__:
|
||||
.globl __try__
|
||||
__try__:
|
||||
push %ebp
|
||||
mov 8(%esp),%ebp
|
||||
|
||||
// void *esp;
|
||||
lea 12(%esp),%eax
|
||||
mov %eax,0*4(%ebp)
|
||||
|
||||
// void *exception_pointers;
|
||||
xor %eax,%eax
|
||||
mov %eax,1*4(%ebp)
|
||||
|
||||
// void *prev;
|
||||
mov %fs:0,%eax
|
||||
mov %eax,2*4(%ebp)
|
||||
|
||||
// void *handler;
|
||||
mov $ seh_handler,%eax
|
||||
mov %eax,3*4(%ebp)
|
||||
|
||||
// void *scopetable;
|
||||
mov $ seh_scopetable,%eax
|
||||
mov %eax,4*4(%ebp)
|
||||
|
||||
// int trylevel;
|
||||
xor %eax,%eax
|
||||
mov %eax,5*4(%ebp)
|
||||
|
||||
// register new SEH
|
||||
lea 2*4(%ebp),%eax
|
||||
mov %eax,%fs:0
|
||||
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
#else
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
/* SEH on x86-64 not implemented */
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
#endif
|
||||
/* ---------------------------------------------- */
|
||||
|
@ -38,21 +38,15 @@ extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]);
|
||||
/* Allow command-line globbing with "int _dowildcard = 1;" in the user source */
|
||||
int _dowildcard;
|
||||
|
||||
#ifdef __x86_64__
|
||||
static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex)
|
||||
{
|
||||
return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex);
|
||||
}
|
||||
#endif
|
||||
|
||||
void _tstart(void)
|
||||
{
|
||||
__TRY__
|
||||
#ifdef __x86_64__
|
||||
SetUnhandledExceptionFilter(catch_sig);
|
||||
#endif
|
||||
_startupinfo start_info = {0};
|
||||
|
||||
SetUnhandledExceptionFilter(catch_sig);
|
||||
// Sets the current application type
|
||||
__set_app_type(_CONSOLE_APP);
|
||||
|
||||
|
@ -26,13 +26,6 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
|
||||
typedef struct { int newmode; } _startupinfo;
|
||||
int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
|
||||
|
||||
#ifdef __x86_64__
|
||||
static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex)
|
||||
{
|
||||
return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int go_winmain(TCHAR *arg1)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
@ -58,13 +51,15 @@ static int go_winmain(TCHAR *arg1)
|
||||
return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
|
||||
}
|
||||
|
||||
static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex)
|
||||
{
|
||||
return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex);
|
||||
}
|
||||
|
||||
int _twinstart(void)
|
||||
{
|
||||
__TRY__
|
||||
#ifdef __x86_64__
|
||||
SetUnhandledExceptionFilter(catch_sig);
|
||||
#endif
|
||||
_startupinfo start_info_con = {0};
|
||||
SetUnhandledExceptionFilter(catch_sig);
|
||||
__set_app_type(__GUI_APP);
|
||||
__tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con);
|
||||
exit(go_winmain(__argc > 1 ? __targv[1] : NULL));
|
||||
|
10
x86_64-gen.c
10
x86_64-gen.c
@ -206,7 +206,7 @@ ST_FUNC void gsym_addr(int t, int a)
|
||||
while (t) {
|
||||
unsigned char *ptr = cur_text_section->data + t;
|
||||
uint32_t n = read32le(ptr); /* next value */
|
||||
write32le(ptr, a - t - 4);
|
||||
write32le(ptr, a < 0 ? -a : a - t - 4);
|
||||
t = n;
|
||||
}
|
||||
}
|
||||
@ -909,7 +909,7 @@ void gfunc_call(int nb_args)
|
||||
|
||||
if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
|
||||
/* need to add the "func_scratch" area after alloca */
|
||||
o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
|
||||
o(0x48); func_alloca = oad(0x05, func_alloca); /* sub $NN, %rax */
|
||||
}
|
||||
|
||||
/* other compilers don't clear the upper bits when returning char/short */
|
||||
@ -1037,11 +1037,7 @@ void gfunc_epilog(void)
|
||||
}
|
||||
|
||||
/* add the "func_scratch" area after each alloca seen */
|
||||
while (func_alloca) {
|
||||
unsigned char *ptr = cur_text_section->data + func_alloca;
|
||||
func_alloca = read32le(ptr);
|
||||
write32le(ptr, func_scratch);
|
||||
}
|
||||
gsym_addr(func_alloca, -func_scratch);
|
||||
|
||||
cur_text_section->data_offset = saved_ind;
|
||||
pe_add_unwind_data(ind, saved_ind, v);
|
||||
|
Loading…
Reference in New Issue
Block a user