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:
grischka 2018-06-08 15:31:40 +02:00
parent 4bb5bc4401
commit ce1ef5b8fc
14 changed files with 111 additions and 231 deletions

View File

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

View File

@ -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
View File

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

View File

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

View File

@ -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
View File

@ -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
View File

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

View File

@ -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)

View File

@ -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 */

View File

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

View File

@ -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
/* ---------------------------------------------- */

View File

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

View File

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

View File

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