DELETED build/tcltcc-0.4-versus-tcc-1rsk.diff Index: build/tcltcc-0.4-versus-tcc-1rsk.diff ================================================================== --- build/tcltcc-0.4-versus-tcc-1rsk.diff +++ build/tcltcc-0.4-versus-tcc-1rsk.diff @@ -1,18436 +0,0 @@ ---- tcc-0.9.24/alloca86.S 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/i386/alloca86.S 2007-11-07 10:04:30.000000000 -0500 -@@ -1,33 +1,41 @@ --/* ---------------------------------------------- */ --/* alloca86.S */ -- --#include "config.h" -- --.globl _alloca -+/* Implementation of alloca() for tinycc (tcc) on x86. -+ * Based on grischka case_8, modified by David A. Wheeler 2007-05-09. -+ * Plays games with stack, so it omits the usual prologue and epilogue. -+ * We use the normal cdecl calling convention to reduce the risk of error. */ -+ -+ -+/* alloca_padding is the minimum number of unused bytes AFTER the allocation. -+ * It must be at LEAST 1 for bound-checking to work, 4 if you want -+ * off-by-one word-writes to not overwrite something important, and 0 -+ * if stack space is an absolute premium */ -+alloca_padding=4 -+ -+/* Alignment: usually 4, 8, or 16. Power of 2. Result % alignment == 0. */ -+alloca_alignment=4 -+ -+.globl _alloca_tcc -+_alloca_tcc: -+ pop %edx /* yank return address from stack */ -+ pop %ecx /* Get parameter (which is size). */ -+ -+ /* See if we got 0, and if so, handle specially. */ -+ or $0,%ecx -+ jz alloc_zero -+ -+ /* Allocate memory on the stack */ -+ mov %ecx,%eax -+ add $(alloca_padding+alloca_alignment-1),%eax -+ and $(-alloca_alignment),%eax -+ sub %eax,%esp /* Allocate! MODIFIES STACK POINTER HERE */ -+ -+ mov %esp,%eax /* Return beginning of allocated area to caller */ -+ push %edx /* Re-allocate param space for the caller to remove */ -+ push %edx /* Restore return address to return to. */ -+ ret - --_alloca: -- pop %edx -- pop %eax -- add $3,%eax -- and $-4,%eax -- jz p3 -- --#ifdef TCC_TARGET_PE --p1: -- cmp $4096,%eax -- jle p2 -- sub $4096,%esp -- sub $4096,%eax -- test %eax,(%esp) -- jmp p1 --p2: --#endif -- -- sub %eax,%esp -- mov %esp,%eax --p3: -- push %edx -- push %edx -+alloc_zero: -+ mov %ecx,%eax /* Return NULL */ -+ push %eax /* Re-allocate param space for the caller to remove */ -+ push %edx /* Restore return address to return to. */ - ret - --/* ---------------------------------------------- */ ---- tcc-0.9.23/bcheck.c 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/bcheck.c 2007-11-07 10:04:32.000000000 -0500 -@@ -3,25 +3,15 @@ - * - * Copyright (c) 2002 Fabrice Bellard - * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * Licensed under LGPL v2.1, see file COPYING in this tarball. - */ - #include - #include - #include - #include --#ifndef __FreeBSD__ -+#if (!defined(__FreeBSD__) && \ -+ !defined(__DragonFly__) && \ -+ !defined(__OpenBSD__)) - #include - #endif - -@@ -36,8 +26,12 @@ - - #define HAVE_MEMALIGN - --#if defined(__FreeBSD__) || defined(__dietlibc__) --#warning Bound checking not fully supported on FreeBSD -+#if (defined(__FreeBSD__) || \ -+ defined(__DragonFly__) || \ -+ defined(__dietlibc__) || \ -+ defined(__UCLIBC__) || \ -+ defined(__OpenBSD__)) -+#warning Bound checking not fully supported in this environment. - #undef CONFIG_TCC_MALLOC_HOOKS - #undef HAVE_MEMALIGN - #endif ---- tcc-0.9.23/Changelog 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/Changelog 2007-11-07 10:04:32.000000000 -0500 -@@ -1,3 +1,15 @@ -+version 0.9.24: -+ -+- ignore AS_NEEDED ld command -+- mark executable sections as executable when running in memory -+- added support for win32 wchar_t (Filip Navara) -+- segment override prefix support (Filip Navara) -+- normalized slashes in paths (Filip Navara) -+- windows style fastcall (Filip Navara) -+- support for empty input register section in asm (Filip Navara) -+- anonymous union/struct support (Filip Navara) -+- fixed parsing of function parameters -+ - version 0.9.23: - - - initial PE executable format for windows version (grischka) ---- tcc-0.9.24/coff.h 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/coff.h 2007-11-07 10:04:32.000000000 -0500 -@@ -37,8 +37,8 @@ - #define F_BYTE_ORDER (F_LITTLE | F_BIG) - #define FILHDR struct filehdr - --//#define FILHSZ sizeof(FILHDR) --#define FILHSZ 22 // above rounds to align on 4 bytes which causes problems -+/*#define FILHSZ sizeof(FILHDR) */ -+#define FILHSZ 22 /* above rounds to align on 4 bytes which causes problems */ - - #define COFF_C67_MAGIC 0x00c2 - -@@ -150,7 +150,7 @@ - /*------------------------------------------------------------------------*/ - /* Define constants for names of "special" sections */ - /*------------------------------------------------------------------------*/ --//#define _TEXT ".text" -+/*#define _TEXT ".text" */ - #define _DATA ".data" - #define _BSS ".bss" - #define _CINIT ".cinit" ---- tcc-0.9.24/elf.h 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/elf.h 2007-11-07 10:04:32.000000000 -0500 -@@ -21,7 +21,7 @@ - #ifndef _ELF_H - #define _ELF_H 1 - --#ifndef _WIN32 -+#ifndef WIN32 - #include - #else - #ifndef __int8_t_defined -@@ -1627,7 +1627,7 @@ - #define R_C60_GOTOFF 9 /* 32 bit offset to GOT */ - #define R_C60_GOTPC 10 /* 32 bit PC relative offset to GOT */ - --#define R_C60HI16 0x55 // high 16 bit MVKH embedded --#define R_C60LO16 0x54 // low 16 bit MVKL embedded -+#define R_C60HI16 0x55 /* high 16 bit MVKH embedded */ -+#define R_C60LO16 0x54 /* low 16 bit MVKL embedded */ - - #endif /* elf.h */ ---- tcc-0.9.24/float.h 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/include/float.h 2007-11-07 10:04:14.000000000 -0500 -@@ -1,57 +1,224 @@ -+/* -+ * float.h -+ * -+ * Constants related to floating point arithmetic. -+ * -+ * Also included here are some non-ANSI bits for accessing the floating -+ * point controller. -+ * -+ * NOTE: GCC provides float.h, and it is probably more accurate than this, -+ * but it doesn't include the non-standard stuff for accessing the -+ * fp controller. (TODO: Move those bits elsewhere?) Thus it is -+ * probably not a good idea to use the GCC supplied version instead -+ * of this header. -+ * -+ * This file is part of the Mingw32 package. -+ * -+ * Contributors: -+ * Created by Colin Peters -+ * -+ * THIS SOFTWARE IS NOT COPYRIGHTED -+ * -+ * This source code is offered for use in the public domain. You may -+ * use, modify or distribute it freely. -+ * -+ * This code is distributed in the hope that it will be useful but -+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY -+ * DISCLAIMED. This includes but is not limited to warranties of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * -+ * $Revision: 1.2 $ -+ * $Author: bellard $ -+ * $Date: 2005/04/17 13:14:29 $ -+ * -+ */ -+ - #ifndef _FLOAT_H_ - #define _FLOAT_H_ - -+/* All the headers include this file. */ -+#include <_mingw.h> -+ -+#define FLT_ROUNDS 1 -+#define FLT_GUARD 1 -+#define FLT_NORMALIZE 1 -+ -+/* -+ * The characteristics of float. -+ */ -+ -+/* The radix for floating point representation. */ - #define FLT_RADIX 2 - --/* IEEE float */ --#define FLT_MANT_DIG 24 -+/* Decimal digits of precision. */ - #define FLT_DIG 6 --#define FLT_ROUNDS 1 -+ -+/* Smallest number such that 1+x != 1 */ - #define FLT_EPSILON 1.19209290e-07F --#define FLT_MIN_EXP (-125) --#define FLT_MIN 1.17549435e-38F --#define FLT_MIN_10_EXP (-37) --#define FLT_MAX_EXP 128 -+ -+/* The number of base FLT_RADIX digits in the mantissa. */ -+#define FLT_MANT_DIG 24 -+ -+/* The maximum floating point number. */ - #define FLT_MAX 3.40282347e+38F -+ -+/* Maximum n such that FLT_RADIX^n - 1 is representable. */ -+#define FLT_MAX_EXP 128 -+ -+/* Maximum n such that 10^n is representable. */ - #define FLT_MAX_10_EXP 38 - --/* IEEE double */ --#define DBL_MANT_DIG 53 -+/* Minimum normalized floating-point number. */ -+#define FLT_MIN 1.17549435e-38F -+ -+/* Minimum n such that FLT_RADIX^n is a normalized number. */ -+#define FLT_MIN_EXP (-125) -+ -+/* Minimum n such that 10^n is a normalized number. */ -+#define FLT_MIN_10_EXP (-37) -+ -+ -+/* -+ * The characteristics of double. -+ */ - #define DBL_DIG 15 --#define DBL_EPSILON 2.2204460492503131e-16 --#define DBL_MIN_EXP (-1021) --#define DBL_MIN 2.2250738585072014e-308 --#define DBL_MIN_10_EXP (-307) --#define DBL_MAX_EXP 1024 -+#define DBL_EPSILON 1.1102230246251568e-16 -+#define DBL_MANT_DIG 53 - #define DBL_MAX 1.7976931348623157e+308 -+#define DBL_MAX_EXP 1024 - #define DBL_MAX_10_EXP 308 -+#define DBL_MIN 2.2250738585072014e-308 -+#define DBL_MIN_EXP (-1021) -+#define DBL_MIN_10_EXP (-307) - --/* horrible intel long double */ --#ifdef __i386__ -- --#define LDBL_MANT_DIG 64 --#define LDBL_DIG 18 --#define LDBL_EPSILON 1.08420217248550443401e-19L --#define LDBL_MIN_EXP (-16381) --#define LDBL_MIN 3.36210314311209350626e-4932L --#define LDBL_MIN_10_EXP (-4931) --#define LDBL_MAX_EXP 16384 --#define LDBL_MAX 1.18973149535723176502e+4932L --#define LDBL_MAX_10_EXP 4932 -- --#else - --/* same as IEEE double */ --#define LDBL_MANT_DIG 53 -+/* -+ * The characteristics of long double. -+ * NOTE: long double is the same as double. -+ */ - #define LDBL_DIG 15 --#define LDBL_EPSILON 2.2204460492503131e-16 --#define LDBL_MIN_EXP (-1021) --#define LDBL_MIN 2.2250738585072014e-308 --#define LDBL_MIN_10_EXP (-307) -+#define LDBL_EPSILON 1.1102230246251568e-16L -+#define LDBL_MANT_DIG 53 -+#define LDBL_MAX 1.7976931348623157e+308L - #define LDBL_MAX_EXP 1024 --#define LDBL_MAX 1.7976931348623157e+308 - #define LDBL_MAX_10_EXP 308 -+#define LDBL_MIN 2.2250738585072014e-308L -+#define LDBL_MIN_EXP (-1021) -+#define LDBL_MIN_10_EXP (-307) -+ -+ -+/* -+ * Functions and definitions for controlling the FPU. -+ */ -+#ifndef __STRICT_ANSI__ -+ -+/* TODO: These constants are only valid for x86 machines */ -+ -+/* Control word masks for unMask */ -+#define _MCW_EM 0x0008001F /* Error masks */ -+#define _MCW_IC 0x00040000 /* Infinity */ -+#define _MCW_RC 0x00000300 /* Rounding */ -+#define _MCW_PC 0x00030000 /* Precision */ -+ -+/* Control word values for unNew (use with related unMask above) */ -+#define _EM_INVALID 0x00000010 -+#define _EM_DENORMAL 0x00080000 -+#define _EM_ZERODIVIDE 0x00000008 -+#define _EM_OVERFLOW 0x00000004 -+#define _EM_UNDERFLOW 0x00000002 -+#define _EM_INEXACT 0x00000001 -+#define _IC_AFFINE 0x00040000 -+#define _IC_PROJECTIVE 0x00000000 -+#define _RC_CHOP 0x00000300 -+#define _RC_UP 0x00000200 -+#define _RC_DOWN 0x00000100 -+#define _RC_NEAR 0x00000000 -+#define _PC_24 0x00020000 -+#define _PC_53 0x00010000 -+#define _PC_64 0x00000000 -+ -+/* These are also defined in Mingw math.h, needed to work around -+ GCC build issues. */ -+/* Return values for fpclass. */ -+#ifndef __MINGW_FPCLASS_DEFINED -+#define __MINGW_FPCLASS_DEFINED 1 -+#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ -+#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ -+#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ -+#define _FPCLASS_NN 0x0008 /* Negative Normal */ -+#define _FPCLASS_ND 0x0010 /* Negative Denormal */ -+#define _FPCLASS_NZ 0x0020 /* Negative Zero */ -+#define _FPCLASS_PZ 0x0040 /* Positive Zero */ -+#define _FPCLASS_PD 0x0080 /* Positive Denormal */ -+#define _FPCLASS_PN 0x0100 /* Positive Normal */ -+#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ -+#endif /* __MINGW_FPCLASS_DEFINED */ -+ -+/* invalid subconditions (_SW_INVALID also set) */ -+#define _SW_UNEMULATED 0x0040 /* unemulated instruction */ -+#define _SW_SQRTNEG 0x0080 /* square root of a neg number */ -+#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ -+#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ -+ -+/* Floating point error signals and return codes */ -+#define _FPE_INVALID 0x81 -+#define _FPE_DENORMAL 0x82 -+#define _FPE_ZERODIVIDE 0x83 -+#define _FPE_OVERFLOW 0x84 -+#define _FPE_UNDERFLOW 0x85 -+#define _FPE_INEXACT 0x86 -+#define _FPE_UNEMULATED 0x87 -+#define _FPE_SQRTNEG 0x88 -+#define _FPE_STACKOVERFLOW 0x8a -+#define _FPE_STACKUNDERFLOW 0x8b -+#define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */ -+ -+#ifndef RC_INVOKED - -+#ifdef __cplusplus -+extern "C" { - #endif - -+/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), -+ * i.e. change the bits in unMask to have the values they have in unNew, -+ * leaving other bits unchanged. */ -+unsigned int _controlfp (unsigned int unNew, unsigned int unMask); -+unsigned int _control87 (unsigned int unNew, unsigned int unMask); -+ -+ -+unsigned int _clearfp (void); /* Clear the FPU status word */ -+unsigned int _statusfp (void); /* Report the FPU status word */ -+#define _clear87 _clearfp -+#define _status87 _statusfp -+ -+void _fpreset (void); /* Reset the FPU */ -+void fpreset (void); -+ -+/* Global 'variable' for the current floating point error code. */ -+int * __fpecode(void); -+#define _fpecode (*(__fpecode())) -+ -+/* -+ * IEEE recommended functions -+ */ -+ -+double _chgsign (double); -+double _copysign (double, double); -+double _logb (double); -+double _nextafter (double, double); -+double _scalb (double, long); -+ -+int _finite (double); -+int _fpclass (double); -+int _isnan (double); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* Not RC_INVOKED */ -+ -+#endif /* Not __STRICT_ANSI__ */ -+ - #endif /* _FLOAT_H_ */ -+ ---- tcc-0.9.23/i386-asm.c 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/i386/i386-asm.c 2007-11-07 10:04:30.000000000 -0500 -@@ -151,6 +151,15 @@ - 0x0f, /* g */ - }; - -+static const uint8_t segment_prefixes[] = { -+ 0x26, /* es */ -+ 0x2e, /* cs */ -+ 0x36, /* ss */ -+ 0x3e, /* ds */ -+ 0x64, /* fs */ -+ 0x65 /* gs */ -+}; -+ - static const ASMInstr asm_instrs[] = { - #define ALT(x) x - #define DEF_ASM_OP0(name, opcode) -@@ -174,11 +183,11 @@ - #include "i386-asm.h" - }; - --static inline int get_reg_shift(TCCState *s1) -+static inline int get_reg_shift(TCCState *st) - { - int shift, v; - -- v = asm_int_expr(s1); -+ v = asm_int_expr(st); - switch(v) { - case 1: - shift = 0; -@@ -193,31 +202,31 @@ - shift = 3; - break; - default: -- expect("1, 2, 4 or 8 constant"); -+ expect(st, "1, 2, 4 or 8 constant"); - shift = 0; - break; - } - return shift; - } - --static int asm_parse_reg(void) -+static int asm_parse_reg(TCCState *st) - { - int reg; - if (tok != '%') - goto error_32; -- next(); -+ next(st); - if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) { - reg = tok - TOK_ASM_eax; -- next(); -+ next(st); - return reg; - } else { - error_32: -- expect("32 bit register"); -+ expect(st, "32 bit register"); - return 0; - } - } - --static void parse_operand(TCCState *s1, Operand *op) -+static void parse_operand(TCCState *st, Operand *op) - { - ExprValue e; - int reg, indir; -@@ -225,12 +234,12 @@ - - indir = 0; - if (tok == '*') { -- next(); -+ next(st); - indir = OP_INDIR; - } - - if (tok == '%') { -- next(); -+ next(st); - if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) { - reg = tok - TOK_ASM_al; - op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ -@@ -250,9 +259,9 @@ - } else if (tok == TOK_ASM_st) { - op->type = OP_ST; - op->reg = 0; -- next(); -+ next(st); - if (tok == '(') { -- next(); -+ next(st); - if (tok != TOK_PPNUM) - goto reg_error; - p = tokc.cstr->data; -@@ -260,22 +269,22 @@ - if ((unsigned)reg >= 8 || p[1] != '\0') - goto reg_error; - op->reg = reg; -- next(); -- skip(')'); -+ next(st); -+ skip(st, ')'); - } - if (op->reg == 0) - op->type |= OP_ST0; - goto no_skip; - } else { - reg_error: -- error("unknown register"); -+ tcc_error(st, "unknown register"); - } -- next(); -+ next(st); - no_skip: ; - } else if (tok == '$') { - /* constant value */ -- next(); -- asm_expr(s1, &e); -+ next(st); -+ asm_expr(st, &e); - op->type = OP_IM32; - op->e.v = e.v; - op->e.sym = e.sym; -@@ -294,7 +303,7 @@ - op->reg2 = -1; - op->shift = 0; - if (tok != '(') { -- asm_expr(s1, &e); -+ asm_expr(st, &e); - op->e.v = e.v; - op->e.sym = e.sym; - } else { -@@ -302,19 +311,21 @@ - op->e.sym = NULL; - } - if (tok == '(') { -- next(); -+ next(st); - if (tok != ',') { -- op->reg = asm_parse_reg(); -+ op->reg = asm_parse_reg(st ); - } - if (tok == ',') { -- next(); -+ next(st); - if (tok != ',') { -- op->reg2 = asm_parse_reg(); -+ op->reg2 = asm_parse_reg(st ); -+ } -+ if (tok == ',') { -+ next(st); -+ op->shift = get_reg_shift(st); - } -- skip(','); -- op->shift = get_reg_shift(s1); - } -- skip(')'); -+ skip(st, ')'); - } - if (op->reg == -1 && op->reg2 == -1) - op->type |= OP_ADDR; -@@ -323,15 +334,15 @@ - } - - /* XXX: unify with C code output ? */ --static void gen_expr32(ExprValue *pe) -+static void gen_expr32(TCCState *st, ExprValue *pe) - { - if (pe->sym) -- greloc(cur_text_section, pe->sym, ind, R_386_32); -- gen_le32(pe->v); -+ greloc(st, cur_text_section, pe->sym, ind, R_386_32); -+ gen_le32(st, pe->v); - } - - /* XXX: unify with C code output ? */ --static void gen_disp32(ExprValue *pe) -+static void gen_disp32(TCCState * st, ExprValue *pe) - { - Sym *sym; - sym = pe->sym; -@@ -341,37 +352,37 @@ - that the TCC compiler behaves differently here because - it always outputs a relocation to ease (future) code - elimination in the linker */ -- gen_le32(pe->v + (long)sym->next - ind - 4); -+ gen_le32(st, pe->v + (long)sym->next - ind - 4); - } else { -- greloc(cur_text_section, sym, ind, R_386_PC32); -- gen_le32(pe->v - 4); -+ greloc(st, cur_text_section, sym, ind, R_386_PC32); -+ gen_le32(st, pe->v - 4); - } - } else { - /* put an empty PC32 relocation */ -- put_elf_reloc(symtab_section, cur_text_section, -+ put_elf_reloc(st, symtab_section, cur_text_section, - ind, R_386_PC32, 0); -- gen_le32(pe->v - 4); -+ gen_le32(st, pe->v - 4); - } - } - - --static void gen_le16(int v) -+static void gen_le16(TCCState *st, int v) - { -- g(v); -- g(v >> 8); -+ g(st, v); -+ g(st, v >> 8); - } - - /* generate the modrm operand */ --static inline void asm_modrm(int reg, Operand *op) -+static inline void asm_modrm(TCCState *st, int reg, Operand *op) - { - int mod, reg1, reg2, sib_reg1; - - if (op->type & (OP_REG | OP_MMX | OP_SSE)) { -- g(0xc0 + (reg << 3) + op->reg); -+ g(st, 0xc0 + (reg << 3) + op->reg); - } else if (op->reg == -1 && op->reg2 == -1) { - /* displacement only */ -- g(0x05 + (reg << 3)); -- gen_expr32(&op->e); -+ g(st, 0x05 + (reg << 3)); -+ gen_expr32(st, &op->e); - } else { - sib_reg1 = op->reg; - /* fist compute displacement encoding */ -@@ -389,47 +400,60 @@ - reg1 = op->reg; - if (op->reg2 != -1) - reg1 = 4; -- g(mod + (reg << 3) + reg1); -+ g(st, mod + (reg << 3) + reg1); - if (reg1 == 4) { - /* add sib byte */ - reg2 = op->reg2; - if (reg2 == -1) - reg2 = 4; /* indicate no index */ -- g((op->shift << 6) + (reg2 << 3) + sib_reg1); -+ g(st, (op->shift << 6) + (reg2 << 3) + sib_reg1); - } - - /* add offset */ - if (mod == 0x40) { -- g(op->e.v); -+ g(st, op->e.v); - } else if (mod == 0x80 || op->reg == -1) { -- gen_expr32(&op->e); -+ gen_expr32(st, &op->e); - } - } - } - --static void asm_opcode(TCCState *s1, int opcode) -+static void asm_opcode(TCCState *st, int opcode) - { - const ASMInstr *pa; -- int i, modrm_index, reg, v, op1, is_short_jmp; -+ int i, modrm_index, reg, v, op1, is_short_jmp, has_seg_prefix; - int nb_ops, s, ss; -- Operand ops[MAX_OPERANDS], *pop; -+ Operand ops[MAX_OPERANDS], *pop, seg_prefix; - int op_type[3]; /* decoded op type */ - - /* get operands */ - pop = ops; - nb_ops = 0; -+ has_seg_prefix = 0; - for(;;) { - if (tok == ';' || tok == TOK_LINEFEED) - break; - if (nb_ops >= MAX_OPERANDS) { -- error("incorrect number of operands"); -+ tcc_error(st, "incorrect number of operands"); -+ } -+ parse_operand(st, pop); -+ if (tok == ':') { -+ if (pop->type != OP_SEG || has_seg_prefix) { -+ tcc_error(st, "incorrect prefix"); -+ } -+ seg_prefix = *pop; -+ has_seg_prefix = 1; -+ next(st); -+ parse_operand(st, pop); -+ if (!(pop->type & OP_EA)) { -+ tcc_error(st, "segment prefix must be followed by memory reference"); -+ } - } -- parse_operand(s1, pop); - pop++; - nb_ops++; - if (tok != ',') - break; -- next(); -+ next(st); - } - - is_short_jmp = 0; -@@ -506,12 +530,12 @@ - int b; - b = op0_codes[opcode - TOK_ASM_pusha]; - if (b & 0xff00) -- g(b >> 8); -- g(b); -+ g(st, b >> 8); -+ g(st, b); - return; - } else { -- error("unknown opcode '%s'", -- get_tok_str(opcode, NULL)); -+ tcc_error(st, "unknown opcode '%s'", -+ get_tok_str(st, opcode, NULL)); - } - } - /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ -@@ -525,19 +549,21 @@ - (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32))) - s = 2; - else -- error("cannot infer opcode suffix"); -+ tcc_error(st, "cannot infer opcode suffix"); - } - } - - /* generate data16 prefix if needed */ - ss = s; - if (s == 1 || (pa->instr_type & OPC_D16)) -- g(WORD_PREFIX_OPCODE); -+ g(st, WORD_PREFIX_OPCODE); - else if (s == 2) - s = 1; - /* now generates the operation */ - if (pa->instr_type & OPC_FWAIT) -- g(0x9b); -+ g(st, 0x9b); -+ if (has_seg_prefix) -+ g(st, segment_prefixes[seg_prefix.reg]); - - v = pa->opcode; - if (v == 0x69 || v == 0x69) { -@@ -602,14 +628,14 @@ - else - v += 0x0f10; - } else { -- error("invalid displacement"); -+ tcc_error(st, "invalid displacement"); - } - } - } - op1 = v >> 8; - if (op1) -- g(op1); -- g(v); -+ g(st, op1); -+ g(st, v); - - /* search which operand will used for modrm */ - modrm_index = 0; -@@ -636,7 +662,7 @@ - goto modrm_found; - } - #ifdef ASM_DEBUG -- error("bad op table"); -+ tcc_error(st, "bad op table"); - #endif - modrm_found: - modrm_index = i; -@@ -651,16 +677,16 @@ - } - } - -- asm_modrm(reg, &ops[modrm_index]); -+ asm_modrm(st, reg, &ops[modrm_index]); - } - - /* emit constants */ - if (pa->opcode == 0x9a || pa->opcode == 0xea) { - /* ljmp or lcall kludge */ -- gen_expr32(&ops[1].e); -+ gen_expr32(st, &ops[1].e); - if (ops[0].e.sym) -- error("cannot relocate"); -- gen_le16(ops[0].e.v); -+ tcc_error(st, "cannot relocate"); -+ gen_le16(st, ops[0].e.v); - } else { - for(i = 0;i < nb_ops; i++) { - v = op_type[i]; -@@ -679,21 +705,21 @@ - if (v & (OP_IM8 | OP_IM8S)) { - if (ops[i].e.sym) - goto error_relocate; -- g(ops[i].e.v); -+ g(st, ops[i].e.v); - } else if (v & OP_IM16) { - if (ops[i].e.sym) { - error_relocate: -- error("cannot relocate"); -+ tcc_error(st, "cannot relocate"); - } -- gen_le16(ops[i].e.v); -+ gen_le16(st, ops[i].e.v); - } else { - if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { - if (is_short_jmp) -- g(ops[i].e.v); -+ g(st, ops[i].e.v); - else -- gen_disp32(&ops[i].e); -+ gen_disp32(st, &ops[i].e); - } else { -- gen_expr32(&ops[i].e); -+ gen_expr32(st, &ops[i].e); - } - } - } -@@ -706,7 +732,7 @@ - - /* return the constraint priority (we allocate first the lowest - numbered constraints) */ --static inline int constraint_priority(const char *str) -+static inline int constraint_priority(TCCState *st, const char *str) - { - int priority, c, pr; - -@@ -744,7 +770,7 @@ - pr = 4; - break; - default: -- error("unknown constraint '%c'", c); -+ tcc_error(st, "unknown constraint '%c'", c); - pr = 0; - } - if (pr > priority) -@@ -765,7 +791,8 @@ - - #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) - --static void asm_compute_constraints(ASMOperand *operands, -+static void asm_compute_constraints(TCCState *st, -+ ASMOperand *operands, - int nb_operands, int nb_outputs, - const uint8_t *clobber_regs, - int *pout_reg) -@@ -791,19 +818,19 @@ - op = &operands[i]; - str = op->constraint; - str = skip_constraint_modifiers(str); -- if (isnum(*str) || *str == '[') { -+ if (isnum(st, *str) || *str == '[') { - /* this is a reference to another constraint */ -- k = find_constraint(operands, nb_operands, str, NULL); -+ k = find_constraint(st, operands, nb_operands, str, NULL); - if ((unsigned)k >= i || i < nb_outputs) -- error("invalid reference in constraint %d ('%s')", -+ tcc_error(st, "invalid reference in constraint %d ('%s')", - i, str); - op->ref_index = k; - if (operands[k].input_index >= 0) -- error("cannot reference twice the same operand"); -+ tcc_error(st, "cannot reference twice the same operand"); - operands[k].input_index = i; - op->priority = 5; - } else { -- op->priority = constraint_priority(str); -+ op->priority = constraint_priority(st, str); - } - } - -@@ -859,7 +886,7 @@ - /* FALL THRU */ - case '&': - if (j >= nb_outputs) -- error("'%c' modifier can only be applied to outputs", c); -+ tcc_error(st, "'%c' modifier can only be applied to outputs", c); - reg_mask = REG_IN_MASK | REG_OUT_MASK; - goto try_next; - case 'A': -@@ -950,7 +977,7 @@ - } - break; - default: -- error("asm constraint %d ('%s') could not be satisfied", -+ tcc_error(st, "asm constraint %d ('%s') could not be satisfied", - j, op->constraint); - break; - } -@@ -973,7 +1000,7 @@ - if (!(regs_allocated[reg] & REG_OUT_MASK)) - goto reg_found2; - } -- error("could not find free output register for reloading"); -+ tcc_error(st, "could not find free output register for reloading"); - reg_found2: - *pout_reg = reg; - break; -@@ -987,7 +1014,7 @@ - op = &operands[j]; - printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", - j, -- op->id ? get_tok_str(op->id, NULL) : "", -+ op->id ? get_tok_str(st, op->id, NULL) : "", - op->constraint, - op->vt->r, - op->reg); -@@ -997,7 +1024,7 @@ - #endif - } - --static void subst_asm_operand(CString *add_str, -+static void subst_asm_operand(TCCState *st, CString *add_str, - SValue *sv, int modifier) - { - int r, reg, size, val; -@@ -1006,11 +1033,11 @@ - r = sv->r; - if ((r & VT_VALMASK) == VT_CONST) { - if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n') -- cstr_ccat(add_str, '$'); -+ cstr_ccat(st, add_str, '$'); - if (r & VT_SYM) { -- cstr_cat(add_str, get_tok_str(sv->sym->v, NULL)); -+ cstr_cat(st, add_str, get_tok_str(st, sv->sym->v, NULL)); - if (sv->c.i != 0) { -- cstr_ccat(add_str, '+'); -+ cstr_ccat(st, add_str, '+'); - } else { - return; - } -@@ -1019,22 +1046,22 @@ - if (modifier == 'n') - val = -val; - snprintf(buf, sizeof(buf), "%d", sv->c.i); -- cstr_cat(add_str, buf); -+ cstr_cat(st, add_str, buf); - } else if ((r & VT_VALMASK) == VT_LOCAL) { - snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i); -- cstr_cat(add_str, buf); -+ cstr_cat(st, add_str, buf); - } else if (r & VT_LVAL) { - reg = r & VT_VALMASK; - if (reg >= VT_CONST) -- error("internal compiler error"); -+ tcc_error(st, "internal compiler error"); - snprintf(buf, sizeof(buf), "(%%%s)", -- get_tok_str(TOK_ASM_eax + reg, NULL)); -- cstr_cat(add_str, buf); -+ get_tok_str(st, TOK_ASM_eax + reg, NULL)); -+ cstr_cat(st, add_str, buf); - } else { - /* register case */ - reg = r & VT_VALMASK; - if (reg >= VT_CONST) -- error("internal compiler error"); -+ tcc_error(st, "internal compiler error"); - - /* choose register operand size */ - if ((sv->type.t & VT_BTYPE) == VT_BYTE) -@@ -1048,11 +1075,11 @@ - - if (modifier == 'b') { - if (reg >= 4) -- error("cannot use byte register"); -+ tcc_error(st, "cannot use byte register"); - size = 1; - } else if (modifier == 'h') { - if (reg >= 4) -- error("cannot use byte register"); -+ tcc_error(st, "cannot use byte register"); - size = -1; - } else if (modifier == 'w') { - size = 2; -@@ -1072,13 +1099,14 @@ - reg = TOK_ASM_eax + reg; - break; - } -- snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL)); -- cstr_cat(add_str, buf); -+ snprintf(buf, sizeof(buf), "%%%s", get_tok_str(st, reg, NULL)); -+ cstr_cat(st, add_str, buf); - } - } - - /* generate prolog and epilog code for asm statment */ --static void asm_gen_code(ASMOperand *operands, int nb_operands, -+static void asm_gen_code(TCCState *st, -+ ASMOperand *operands, int nb_operands, - int nb_outputs, int is_output, - uint8_t *clobber_regs, - int out_reg) -@@ -1100,7 +1128,7 @@ - for(i = 0; i < NB_SAVED_REGS; i++) { - reg = reg_saved[i]; - if (regs_allocated[reg]) -- g(0x50 + reg); -+ g(st, 0x50 + reg); - } - - /* generate load code */ -@@ -1114,15 +1142,15 @@ - SValue sv; - sv = *op->vt; - sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; -- load(op->reg, &sv); -+ load(st, op->reg, &sv); - } else if (i >= nb_outputs || op->is_rw) { - /* load value in register */ -- load(op->reg, op->vt); -+ load(st, op->reg, op->vt); - if (op->is_llong) { - SValue sv; - sv = *op->vt; - sv.c.ul += 4; -- load(TREG_EDX, &sv); -+ load(st, TREG_EDX, &sv); - } - } - } -@@ -1137,18 +1165,18 @@ - SValue sv; - sv = *op->vt; - sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; -- load(out_reg, &sv); -+ load(st, out_reg, &sv); - - sv.r = (sv.r & ~VT_VALMASK) | out_reg; -- store(op->reg, &sv); -+ store(st, op->reg, &sv); - } - } else { -- store(op->reg, op->vt); -+ store(st, op->reg, op->vt); - if (op->is_llong) { - SValue sv; - sv = *op->vt; - sv.c.ul += 4; -- store(TREG_EDX, &sv); -+ store(st, TREG_EDX, &sv); - } - } - } -@@ -1157,12 +1185,12 @@ - for(i = NB_SAVED_REGS - 1; i >= 0; i--) { - reg = reg_saved[i]; - if (regs_allocated[reg]) -- g(0x58 + reg); -+ g(st, 0x58 + reg); - } - } - } - --static void asm_clobber(uint8_t *clobber_regs, const char *str) -+static void asm_clobber(TCCState *st, uint8_t *clobber_regs, const char *str) - { - int reg; - TokenSym *ts; -@@ -1170,14 +1198,14 @@ - if (!strcmp(str, "memory") || - !strcmp(str, "cc")) - return; -- ts = tok_alloc(str, strlen(str)); -+ ts = tok_alloc(st, str, strlen(str)); - reg = ts->tok; - if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) { - reg -= TOK_ASM_eax; - } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) { - reg -= TOK_ASM_ax; - } else { -- error("invalid clobber register '%s'", str); -+ tcc_error(st, "invalid clobber register '%s'", str); - } - clobber_regs[reg] = 1; - } ---- tcc-0.9.24/i386-asm.h 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/i386/i386-asm.h 2007-11-07 10:04:30.000000000 -0500 -@@ -154,6 +154,7 @@ - /* arith */ - ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ - ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -+ALT(DEF_ASM_OP2(addb, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) - ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) - ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) - ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) ---- tcc-0.9.24/i386-gen.c 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/i386/i386-gen.c 2007-11-07 10:04:30.000000000 -0500 -@@ -59,7 +59,7 @@ - - /* defined if structures are passed as pointers. Otherwise structures - are directly pushed on stack. */ --//#define FUNC_STRUCT_PARAM_AS_PTR -+/*#define FUNC_STRUCT_PARAM_AS_PTR */ - - /* pointer size, in bytes */ - #define PTR_SIZE 4 -@@ -90,36 +90,39 @@ - static int func_ret_sub; - - /* XXX: make it faster ? */ --void g(int c) -+void g(TCCState *st, int c) - { - int ind1; -+ -+ if (!cur_text_section) return; - ind1 = ind + 1; - if (ind1 > cur_text_section->data_allocated) -- section_realloc(cur_text_section, ind1); -+ section_realloc(st, cur_text_section, ind1); - cur_text_section->data[ind] = c; - ind = ind1; - } - --void o(unsigned int c) -+void o(TCCState *st, unsigned int c) - { - while (c) { -- g(c); -+ g(st, c); - c = c >> 8; - } - } - --void gen_le32(int c) -+void gen_le32(TCCState *st, int c) - { -- g(c); -- g(c >> 8); -- g(c >> 16); -- g(c >> 24); -+ g(st,c); -+ g(st,c >> 8); -+ g(st,c >> 16); -+ g(st,c >> 24); - } - - /* output a symbol and patch all calls to it */ - void gsym_addr(int t, int a) - { - int n, *ptr; -+ if (!cur_text_section) return; - while (t) { - ptr = (int *)(cur_text_section->data + t); - n = *ptr; /* next value */ -@@ -138,14 +141,15 @@ - #define psym oad - - /* instruction + 4 bytes data. Return the address of the data */ --static int oad(int c, int s) -+static int oad(TCCState *st, int c, int s) - { - int ind1; - -- o(c); -+ if (!cur_text_section) return 0; -+ o(st, c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) -- section_realloc(cur_text_section, ind1); -+ section_realloc(st, cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; - s = ind; - ind = ind1; -@@ -153,39 +157,39 @@ - } - - /* output constant with relocation if 'r & VT_SYM' is true */ --static void gen_addr32(int r, Sym *sym, int c) -+static void gen_addr32(TCCState *st, int r, Sym *sym, int c) - { - if (r & VT_SYM) -- greloc(cur_text_section, sym, ind, R_386_32); -- gen_le32(c); -+ greloc(st, cur_text_section, sym, ind, R_386_32); -+ gen_le32(st, c); - } - - /* generate a modrm reference. 'op_reg' contains the addtionnal 3 - opcode bits */ --static void gen_modrm(int op_reg, int r, Sym *sym, int c) -+static void gen_modrm(TCCState *st, int op_reg, int r, Sym *sym, int c) - { - op_reg = op_reg << 3; - if ((r & VT_VALMASK) == VT_CONST) { - /* constant memory reference */ -- o(0x05 | op_reg); -- gen_addr32(r, sym, c); -+ o(st, 0x05 | op_reg); -+ gen_addr32(st, r, sym, c); - } else if ((r & VT_VALMASK) == VT_LOCAL) { - /* currently, we use only ebp as base */ - if (c == (char)c) { - /* short reference */ -- o(0x45 | op_reg); -- g(c); -+ o(st,0x45 | op_reg); -+ g(st, c); - } else { -- oad(0x85 | op_reg, c); -+ oad(st, 0x85 | op_reg, c); - } - } else { -- g(0x00 | op_reg | (r & VT_VALMASK)); -+ g(st, 0x00 | op_reg | (r & VT_VALMASK)); - } - } - - - /* load 'r' from value 'sv' */ --void load(int r, SValue *sv) -+void load(TCCState *st, int r, SValue *sv) - { - int v, t, ft, fc, fr; - SValue v1; -@@ -200,57 +204,57 @@ - v1.type.t = VT_INT; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; -- load(r, &v1); -+ load(st, r, &v1); - fr = r; - } - if ((ft & VT_BTYPE) == VT_FLOAT) { -- o(0xd9); /* flds */ -+ o(st, 0xd9); /* flds */ - r = 0; - } else if ((ft & VT_BTYPE) == VT_DOUBLE) { -- o(0xdd); /* fldl */ -+ o(st, 0xdd); /* fldl */ - r = 0; - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { -- o(0xdb); /* fldt */ -+ o(st, 0xdb); /* fldt */ - r = 5; - } else if ((ft & VT_TYPE) == VT_BYTE) { -- o(0xbe0f); /* movsbl */ -+ o(st, 0xbe0f); /* movsbl */ - } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { -- o(0xb60f); /* movzbl */ -+ o(st, 0xb60f); /* movzbl */ - } else if ((ft & VT_TYPE) == VT_SHORT) { -- o(0xbf0f); /* movswl */ -+ o(st, 0xbf0f); /* movswl */ - } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { -- o(0xb70f); /* movzwl */ -+ o(st, 0xb70f); /* movzwl */ - } else { -- o(0x8b); /* movl */ -+ o(st, 0x8b); /* movl */ - } -- gen_modrm(r, fr, sv->sym, fc); -+ gen_modrm(st, r, fr, sv->sym, fc); - } else { - if (v == VT_CONST) { -- o(0xb8 + r); /* mov $xx, r */ -- gen_addr32(fr, sv->sym, fc); -+ o(st, 0xb8 + r); /* mov $xx, r */ -+ gen_addr32(st, fr, sv->sym, fc); - } else if (v == VT_LOCAL) { -- o(0x8d); /* lea xxx(%ebp), r */ -- gen_modrm(r, VT_LOCAL, sv->sym, fc); -+ o(st, 0x8d); /* lea xxx(%ebp), r */ -+ gen_modrm(st, r, VT_LOCAL, sv->sym, fc); - } else if (v == VT_CMP) { -- oad(0xb8 + r, 0); /* mov $0, r */ -- o(0x0f); /* setxx %br */ -- o(fc); -- o(0xc0 + r); -+ oad(st, 0xb8 + r, 0); /* mov $0, r */ -+ o(st, 0x0f); /* setxx %br */ -+ o(st, fc); -+ o(st, 0xc0 + r); - } else if (v == VT_JMP || v == VT_JMPI) { - t = v & 1; -- oad(0xb8 + r, t); /* mov $1, r */ -- o(0x05eb); /* jmp after */ -+ oad(st, 0xb8 + r, t); /* mov $1, r */ -+ o(st, 0x05eb); /* jmp after */ - gsym(fc); -- oad(0xb8 + r, t ^ 1); /* mov $0, r */ -+ oad(st, 0xb8 + r, t ^ 1); /* mov $0, r */ - } else if (v != r) { -- o(0x89); -- o(0xc0 + r + v * 8); /* mov v, r */ -+ o(st, 0x89); -+ o(st, 0xc0 + r + v * 8); /* mov v, r */ - } - } - } - - /* store register 'r' in lvalue 'v' */ --void store(int r, SValue *v) -+void store(TCCState *st, int r, SValue *v) - { - int fr, bt, ft, fc; - -@@ -260,63 +264,63 @@ - bt = ft & VT_BTYPE; - /* XXX: incorrect if float reg to reg */ - if (bt == VT_FLOAT) { -- o(0xd9); /* fsts */ -+ o(st, 0xd9); /* fsts */ - r = 2; - } else if (bt == VT_DOUBLE) { -- o(0xdd); /* fstpl */ -+ o(st, 0xdd); /* fstpl */ - r = 2; - } else if (bt == VT_LDOUBLE) { -- o(0xc0d9); /* fld %st(0) */ -- o(0xdb); /* fstpt */ -+ o(st, 0xc0d9); /* fld %st(0) */ -+ o(st, 0xdb); /* fstpt */ - r = 7; - } else { - if (bt == VT_SHORT) -- o(0x66); -+ o(st, 0x66); - if (bt == VT_BYTE || bt == VT_BOOL) -- o(0x88); -+ o(st, 0x88); - else -- o(0x89); -+ o(st, 0x89); - } - if (fr == VT_CONST || - fr == VT_LOCAL || - (v->r & VT_LVAL)) { -- gen_modrm(r, v->r, v->sym, fc); -+ gen_modrm(st, r, v->r, v->sym, fc); - } else if (fr != r) { -- o(0xc0 + fr + r * 8); /* mov r, fr */ -+ o(st, 0xc0 + fr + r * 8); /* mov r, fr */ - } - } - --static void gadd_sp(int val) -+static void gadd_sp(TCCState *st, int val) - { - if (val == (char)val) { -- o(0xc483); -- g(val); -+ o(st, 0xc483); -+ g(st, val); - } else { -- oad(0xc481, val); /* add $xxx, %esp */ -+ oad(st, 0xc481, val); /* add $xxx, %esp */ - } - } - - /* 'is_jmp' is '1' if it is a jump */ --static void gcall_or_jmp(int is_jmp) -+static void gcall_or_jmp(TCCState *st, int is_jmp) - { - int r; - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ -- greloc(cur_text_section, vtop->sym, -+ greloc(st, cur_text_section, vtop->sym, - ind + 1, R_386_PC32); - } else { - /* put an empty PC32 relocation */ -- put_elf_reloc(symtab_section, cur_text_section, -+ put_elf_reloc(st, symtab_section, cur_text_section, - ind + 1, R_386_PC32, 0); - } -- oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ -+ oad(st, 0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ - } else { - /* otherwise, indirect call */ -- r = gv(RC_INT); -- o(0xff); /* call/jmp *r */ -- o(0xd0 + r + (is_jmp << 4)); -+ r = gv(st, RC_INT); -+ o(st, 0xff); /* call/jmp *r */ -+ o(st, 0xd0 + r + (is_jmp << 4)); - } - } - -@@ -326,7 +330,7 @@ - /* Generate function call. The function address is pushed first, then - all the parameters in call order. This functions pops all the - parameters and the function address. */ --void gfunc_call(int nb_args) -+void gfunc_call(TCCState *st, int nb_args) - { - int size, align, r, args_size, i, func_call; - Sym *func_sym; -@@ -334,53 +338,53 @@ - args_size = 0; - for(i = 0;i < nb_args; i++) { - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { -- size = type_size(&vtop->type, &align); -+ size = type_size(st, &vtop->type, &align); - /* align to stack align size */ - size = (size + 3) & ~3; - /* allocate the necessary size on stack */ -- oad(0xec81, size); /* sub $xxx, %esp */ -+ oad(st, 0xec81, size); /* sub $xxx, %esp */ - /* generate structure store */ -- r = get_reg(RC_INT); -- o(0x89); /* mov %esp, r */ -- o(0xe0 + r); -- vset(&vtop->type, r | VT_LVAL, 0); -- vswap(); -- vstore(); -+ r = get_reg(st, RC_INT); -+ o(st, 0x89); /* mov %esp, r */ -+ o(st, 0xe0 + r); -+ vset(st, &vtop->type, r | VT_LVAL, 0); -+ vswap(st); -+ vstore(st); - args_size += size; -- } else if (is_float(vtop->type.t)) { -- gv(RC_FLOAT); /* only one float register */ -+ } else if (is_float(st, vtop->type.t)) { -+ gv(st, RC_FLOAT); /* only one float register */ - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) - size = 4; - else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) - size = 8; - else - size = 12; -- oad(0xec81, size); /* sub $xxx, %esp */ -+ oad(st, 0xec81, size); /* sub $xxx, %esp */ - if (size == 12) -- o(0x7cdb); -+ o(st, 0x7cdb); - else -- o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ -- g(0x24); -- g(0x00); -+ o(st, 0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ -+ g(st, 0x24); -+ g(st, 0x00); - args_size += size; - } else { - /* simple type (currently always same size) */ - /* XXX: implicit cast ? */ -- r = gv(RC_INT); -+ r = gv(st, RC_INT); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - size = 8; -- o(0x50 + vtop->r2); /* push r */ -+ o(st, 0x50 + vtop->r2); /* push r */ - } else { - size = 4; - } -- o(0x50 + r); /* push r */ -+ o(st, 0x50 + r); /* push r */ - args_size += size; - } - vtop--; - } -- save_regs(0); /* save used temporary registers */ -+ save_regs(st, 0); /* save used temporary registers */ - func_sym = vtop->type.ref; -- func_call = FUNC_CALL(func_sym->r); -+ func_call = func_sym->r; - /* fast call case */ - if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || - func_call == FUNC_FASTCALLW) { -@@ -396,25 +400,21 @@ - for(i = 0;i < fastcall_nb_regs; i++) { - if (args_size <= 0) - break; -- o(0x58 + fastcall_regs_ptr[i]); /* pop r */ -+ o(st, 0x58 + fastcall_regs_ptr[i]); /* pop r */ - /* XXX: incorrect for struct/floats */ - args_size -= 4; - } - } -- gcall_or_jmp(0); -- if (args_size && func_call != FUNC_STDCALL) -- gadd_sp(args_size); -+ gcall_or_jmp(st, 0); -+ if (args_size && func_sym->r != FUNC_STDCALL) -+ gadd_sp(st, args_size); - vtop--; - } - --#ifdef TCC_TARGET_PE --#define FUNC_PROLOG_SIZE 10 --#else - #define FUNC_PROLOG_SIZE 9 --#endif - - /* generate function prolog of type 't' */ --void gfunc_prolog(CType *func_type) -+void gfunc_prolog(TCCState *st, CType *func_type) - { - int addr, align, size, func_call, fastcall_nb_regs; - int param_index, param_addr; -@@ -423,7 +423,7 @@ - CType *type; - - sym = func_type->ref; -- func_call = FUNC_CALL(sym->r); -+ func_call = sym->r; - addr = 8; - loc = 0; - if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { -@@ -452,7 +452,7 @@ - /* define parameters */ - while ((sym = sym->next) != NULL) { - type = &sym->type; -- size = type_size(type, &align); -+ size = type_size(st, type, &align); - size = (size + 3) & ~3; - #ifdef FUNC_STRUCT_PARAM_AS_PTR - /* structs are passed as pointer */ -@@ -463,14 +463,14 @@ - if (param_index < fastcall_nb_regs) { - /* save FASTCALL register */ - loc -= 4; -- o(0x89); /* movl */ -- gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc); -+ o(st, 0x89); /* movl */ -+ gen_modrm(st,fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc); - param_addr = loc; - } else { - param_addr = addr; - addr += size; - } -- sym_push(sym->v & ~SYM_FIELD, type, -+ sym_push(st, sym->v & ~SYM_FIELD, type, - VT_LOCAL | VT_LVAL, param_addr); - param_index++; - } -@@ -481,57 +481,57 @@ - - /* leave some room for bound checking code */ - if (do_bounds_check) { -- oad(0xb8, 0); /* lbound section pointer */ -- oad(0xb8, 0); /* call to function */ -+ oad(st, 0xb8, 0); /* lbound section pointer */ -+ oad(st, 0xb8, 0); /* call to function */ - func_bound_offset = lbounds_section->data_offset; - } - } - - /* generate function epilog */ --void gfunc_epilog(void) -+void gfunc_epilog(TCCState *st) - { - int v, saved_ind; - --#ifdef CONFIG_TCC_BCHECK -+#if 0 - if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) { - int saved_ind; - int *bounds_ptr; - Sym *sym, *sym_data; - /* add end of table info */ -- bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); -+ bounds_ptr = section_ptr_add(st,lbounds_section, sizeof(int)); - *bounds_ptr = 0; - /* generate bound local allocation */ - saved_ind = ind; - ind = func_sub_sp_offset; -- sym_data = get_sym_ref(&char_pointer_type, lbounds_section, -+ sym_data = get_sym_ref(st,&char_pointer_type, lbounds_section, - func_bound_offset, lbounds_section->data_offset); -- greloc(cur_text_section, sym_data, -+ greloc(st, cur_text_section, sym_data, - ind + 1, R_386_32); -- oad(0xb8, 0); /* mov %eax, xxx */ -- sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0); -- greloc(cur_text_section, sym, -+ oad(st, 0xb8, 0); /* mov %eax, xxx */ -+ sym = external_global_sym(st, TOK___bound_local_new, &func_old_type, 0); -+ greloc(st, cur_text_section, sym, - ind + 1, R_386_PC32); -- oad(0xe8, -4); -+ oad(st, 0xe8, -4); - ind = saved_ind; - /* generate bound check local freeing */ -- o(0x5250); /* save returned value, if any */ -- greloc(cur_text_section, sym_data, -+ o(st, 0x5250); /* save returned value, if any */ -+ greloc(st, cur_text_section, sym_data, - ind + 1, R_386_32); -- oad(0xb8, 0); /* mov %eax, xxx */ -- sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0); -- greloc(cur_text_section, sym, -+ oad(st, 0xb8, 0); /* mov %eax, xxx */ -+ sym = external_global_sym(st, TOK___bound_local_delete, &func_old_type, 0); -+ greloc(st, ur_text_section, sym, - ind + 1, R_386_PC32); -- oad(0xe8, -4); -- o(0x585a); /* restore returned value, if any */ -+ oad(st, 0xe8, -4); -+ o(st, 0x585a); /* restore returned value, if any */ - } - #endif -- o(0xc9); /* leave */ -+ o(st, 0xc9); /* leave */ - if (func_ret_sub == 0) { -- o(0xc3); /* ret */ -+ o(st, 0xc3); /* ret */ - } else { -- o(0xc2); /* ret n */ -- g(func_ret_sub); -- g(func_ret_sub >> 8); -+ o(st, 0xc2); /* ret n */ -+ g(st, func_ret_sub); -+ g(st, func_ret_sub >> 8); - } - /* align local size to word & save local variables */ - -@@ -540,52 +540,48 @@ - ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; - #ifdef TCC_TARGET_PE - if (v >= 4096) { -- Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); -- oad(0xb8, v); /* mov stacksize, %eax */ -- oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ -- greloc(cur_text_section, sym, ind-4, R_386_PC32); -+ Sym *sym = external_global_sym(st, TOK___chkstk, &func_old_type, 0); -+ oad(st, 0xe8, -4); /* call __chkstk, (does the stackframe too) */ -+ greloc(st, cur_text_section, sym, ind-4, R_386_PC32); - } else - #endif - { -- o(0xe58955); /* push %ebp, mov %esp, %ebp */ -- o(0xec81); /* sub esp, stacksize */ -- gen_le32(v); --#if FUNC_PROLOG_SIZE == 10 -- o(0x90); /* adjust to FUNC_PROLOG_SIZE */ --#endif -+ o(st, 0xe58955); /* push %ebp, mov %esp, %ebp */ -+ o(st, 0xec81); /* sub esp, stacksize */ - } -+ gen_le32(st, v); - ind = saved_ind; - } - - /* generate a jump to a label */ --int gjmp(int t) -+int gjmp(TCCState *st, int t) - { -- return psym(0xe9, t); -+ return psym(st, 0xe9, t); - } - - /* generate a jump to a fixed address */ --void gjmp_addr(int a) -+void gjmp_addr(TCCState *st, int a) - { - int r; - r = a - ind - 2; - if (r == (char)r) { -- g(0xeb); -- g(r); -+ g(st, 0xeb); -+ g(st, r); - } else { -- oad(0xe9, a - ind - 5); -+ oad(st, 0xe9, a - ind - 5); - } - } - - /* generate a test. set 'inv' to invert test. Stack entry is popped */ --int gtst(int inv, int t) -+int gtst(TCCState *st, int inv, int t) - { - int v, *p; - - v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - /* fast case : can jump directly since flags are set */ -- g(0x0f); -- t = psym((vtop->c.i - 16) ^ inv, t); -+ g(st, 0x0f); -+ t = psym(st, (vtop->c.i - 16) ^ inv, t); - } else if (v == VT_JMP || v == VT_JMPI) { - /* && or || optimization */ - if ((v & 1) == inv) { -@@ -596,25 +592,25 @@ - *p = t; - t = vtop->c.i; - } else { -- t = gjmp(t); -+ t = gjmp(st, t); - gsym(vtop->c.i); - } - } else { -- if (is_float(vtop->type.t) || -- (vtop->type.t & VT_BTYPE) == VT_LLONG) { -- vpushi(0); -- gen_op(TOK_NE); -+ if (is_float(st, vtop->type.t) || is_llong(st, vtop->type.t)) { -+ /* compare != 0 to get a 32-bit int for testing */ -+ vpushi(st, 0); -+ gen_op(st, TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) -- t = gjmp(t); -+ t = gjmp(st,t); - } else { -- v = gv(RC_INT); -- o(0x85); -- o(0xc0 + v * 9); -- g(0x0f); -- t = psym(0x85 ^ inv, t); -+ v = gv(st, RC_INT); -+ o(st, 0x85); -+ o(st, 0xc0 + v * 9); -+ g(st, 0x0f); -+ t = psym(st, 0x85 ^ inv, t); - } - } - vtop--; -@@ -622,7 +618,7 @@ - } - - /* generate an integer binary operation */ --void gen_opi(int op) -+void gen_opi(TCCState *st, int op) - { - int r, fr, opc, c; - -@@ -633,25 +629,25 @@ - gen_op8: - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant case */ -- vswap(); -- r = gv(RC_INT); -- vswap(); -+ vswap(st); -+ r = gv(st, RC_INT); -+ vswap(st); - c = vtop->c.i; - if (c == (char)c) { - /* XXX: generate inc and dec for smaller code ? */ -- o(0x83); -- o(0xc0 | (opc << 3) | r); -- g(c); -+ o(st, 0x83); -+ o(st, 0xc0 | (opc << 3) | r); -+ g(st, c); - } else { -- o(0x81); -- oad(0xc0 | (opc << 3) | r, c); -+ o(st, 0x81); -+ oad(st, 0xc0 | (opc << 3) | r, c); - } - } else { -- gv2(RC_INT, RC_INT); -+ gv2(st, RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; -- o((opc << 3) | 0x01); -- o(0xc0 + r + fr * 8); -+ o(st, (opc << 3) | 0x01); -+ o(st, 0xc0 + r + fr * 8); - } - vtop--; - if (op >= TOK_ULT && op <= TOK_GT) { -@@ -679,12 +675,12 @@ - opc = 1; - goto gen_op8; - case '*': -- gv2(RC_INT, RC_INT); -+ gv2(st, RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; -- o(0xaf0f); /* imul fr, r */ -- o(0xc0 + fr + r * 8); -+ o(st, 0xaf0f); /* imul fr, r */ -+ o(st, 0xc0 + fr + r * 8); - break; - case TOK_SHL: - opc = 4; -@@ -698,19 +694,19 @@ - opc = 0xc0 | (opc << 3); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant case */ -- vswap(); -- r = gv(RC_INT); -- vswap(); -+ vswap(st); -+ r = gv(st, RC_INT); -+ vswap(st); - c = vtop->c.i & 0x1f; -- o(0xc1); /* shl/shr/sar $xxx, r */ -- o(opc | r); -- g(c); -+ o(st, 0xc1); /* shl/shr/sar $xxx, r */ -+ o(st, opc | r); -+ g(st, c); - } else { - /* we generate the shift in ecx */ -- gv2(RC_INT, RC_ECX); -+ gv2(st, RC_INT, RC_ECX); - r = vtop[-1].r; -- o(0xd3); /* shl/shr/sar %cl, r */ -- o(opc | r); -+ o(st, 0xd3); /* shl/shr/sar %cl, r */ -+ o(st, opc | r); - } - vtop--; - break; -@@ -722,23 +718,23 @@ - case TOK_UMULL: - /* first operand must be in eax */ - /* XXX: need better constraint for second operand */ -- gv2(RC_EAX, RC_ECX); -+ gv2(st, RC_EAX, RC_ECX); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; -- save_reg(TREG_EDX); -+ save_reg(st, TREG_EDX); - if (op == TOK_UMULL) { -- o(0xf7); /* mul fr */ -- o(0xe0 + fr); -+ o(st, 0xf7); /* mul fr */ -+ o(st, 0xe0 + fr); - vtop->r2 = TREG_EDX; - r = TREG_EAX; - } else { - if (op == TOK_UDIV || op == TOK_UMOD) { -- o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ -- o(0xf0 + fr); -+ o(st, 0xf7d231); /* xor %edx, %edx, div fr, %eax */ -+ o(st, 0xf0 + fr); - } else { -- o(0xf799); /* cltd, idiv fr, %eax */ -- o(0xf8 + fr); -+ o(st, 0xf799); /* cltd, idiv fr, %eax */ -+ o(st, 0xf8 + fr); - } - if (op == '%' || op == TOK_UMOD) - r = TREG_EDX; -@@ -756,57 +752,57 @@ - /* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ - /* XXX: need to use ST1 too */ --void gen_opf(int op) -+void gen_opf(TCCState *st, int op) - { - int a, ft, fc, swapped, r; - - /* convert constants to memory references */ - if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { -- vswap(); -- gv(RC_FLOAT); -- vswap(); -+ vswap(st); -+ gv(st, RC_FLOAT); -+ vswap(st); - } - if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) -- gv(RC_FLOAT); -+ gv(st, RC_FLOAT); - - /* must put at least one value in the floating point register */ - if ((vtop[-1].r & VT_LVAL) && - (vtop[0].r & VT_LVAL)) { -- vswap(); -- gv(RC_FLOAT); -- vswap(); -+ vswap(st); -+ gv(st, RC_FLOAT); -+ vswap(st); - } - swapped = 0; - /* swap the stack if needed so that t1 is the register and t2 is - the memory reference */ - if (vtop[-1].r & VT_LVAL) { -- vswap(); -+ vswap(st); - swapped = 1; - } - if (op >= TOK_ULT && op <= TOK_GT) { - /* load on stack second operand */ -- load(TREG_ST0, vtop); -- save_reg(TREG_EAX); /* eax is used by FP comparison code */ -+ load(st, TREG_ST0, vtop); -+ save_reg(st, TREG_EAX); /* eax is used by FP comparison code */ - if (op == TOK_GE || op == TOK_GT) - swapped = !swapped; - else if (op == TOK_EQ || op == TOK_NE) - swapped = 0; - if (swapped) -- o(0xc9d9); /* fxch %st(1) */ -- o(0xe9da); /* fucompp */ -- o(0xe0df); /* fnstsw %ax */ -+ o(st, 0xc9d9); /* fxch %st(1) */ -+ o(st, 0xe9da); /* fucompp */ -+ o(st, 0xe0df); /* fnstsw %ax */ - if (op == TOK_EQ) { -- o(0x45e480); /* and $0x45, %ah */ -- o(0x40fC80); /* cmp $0x40, %ah */ -+ o(st, 0x45e480); /* and $0x45, %ah */ -+ o(st, 0x40fC80); /* cmp $0x40, %ah */ - } else if (op == TOK_NE) { -- o(0x45e480); /* and $0x45, %ah */ -- o(0x40f480); /* xor $0x40, %ah */ -+ o(st, 0x45e480); /* and $0x45, %ah */ -+ o(st, 0x40f480); /* xor $0x40, %ah */ - op = TOK_NE; - } else if (op == TOK_GE || op == TOK_LE) { -- o(0x05c4f6); /* test $0x05, %ah */ -+ o(st, 0x05c4f6); /* test $0x05, %ah */ - op = TOK_EQ; - } else { -- o(0x45c4f6); /* test $0x45, %ah */ -+ o(st, 0x45c4f6); /* test $0x45, %ah */ - op = TOK_EQ; - } - vtop--; -@@ -815,7 +811,7 @@ - } else { - /* no memory reference possible for long double operations */ - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { -- load(TREG_ST0, vtop); -+ load(st, TREG_ST0, vtop); - swapped = !swapped; - } - -@@ -841,26 +837,26 @@ - ft = vtop->type.t; - fc = vtop->c.ul; - if ((ft & VT_BTYPE) == VT_LDOUBLE) { -- o(0xde); /* fxxxp %st, %st(1) */ -- o(0xc1 + (a << 3)); -+ o(st, 0xde); /* fxxxp %st, %st(1) */ -+ o(st, 0xc1 + (a << 3)); - } else { - /* if saved lvalue, then we must reload it */ - r = vtop->r; - if ((r & VT_VALMASK) == VT_LLOCAL) { - SValue v1; -- r = get_reg(RC_INT); -+ r = get_reg(st, RC_INT); - v1.type.t = VT_INT; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; -- load(r, &v1); -+ load(st, r, &v1); - fc = 0; - } - - if ((ft & VT_BTYPE) == VT_DOUBLE) -- o(0xdc); -+ o(st, 0xdc); - else -- o(0xd8); -- gen_modrm(a, r, vtop->sym, fc); -+ o(st, 0xd8); -+ gen_modrm(st, a, r, vtop->sym, fc); - } - vtop--; - } -@@ -868,37 +864,37 @@ - - /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' - and 'long long' cases. */ --void gen_cvt_itof(int t) -+void gen_cvt_itof(TCCState *st, int t) - { -- save_reg(TREG_ST0); -- gv(RC_INT); -+ save_reg(st, TREG_ST0); -+ gv(st, RC_INT); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - /* signed long long to float/double/long double (unsigned case - is handled generically) */ -- o(0x50 + vtop->r2); /* push r2 */ -- o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ -- o(0x242cdf); /* fildll (%esp) */ -- o(0x08c483); /* add $8, %esp */ -+ o(st, 0x50 + vtop->r2); /* push r2 */ -+ o(st, 0x50 + (vtop->r & VT_VALMASK)); /* push r */ -+ o(st, 0x242cdf); /* fildll (%esp) */ -+ o(st, 0x08c483); /* add $8, %esp */ - } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == - (VT_INT | VT_UNSIGNED)) { - /* unsigned int to float/double/long double */ -- o(0x6a); /* push $0 */ -- g(0x00); -- o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ -- o(0x242cdf); /* fildll (%esp) */ -- o(0x08c483); /* add $8, %esp */ -+ o(st, 0x6a); /* push $0 */ -+ g(st, 0x00); -+ o(st, 0x50 + (vtop->r & VT_VALMASK)); /* push r */ -+ o(st, 0x242cdf); /* fildll (%esp) */ -+ o(st, 0x08c483); /* add $8, %esp */ - } else { - /* int to float/double/long double */ -- o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ -- o(0x2404db); /* fildl (%esp) */ -- o(0x04c483); /* add $4, %esp */ -+ o(st, 0x50 + (vtop->r & VT_VALMASK)); /* push r */ -+ o(st, 0x2404db); /* fildl (%esp) */ -+ o(st, 0x04c483); /* add $4, %esp */ - } - vtop->r = TREG_ST0; - } - - /* convert fp to int 't' type */ - /* XXX: handle long long case */ --void gen_cvt_ftoi(int t) -+void gen_cvt_ftoi(TCCState *st, int t) - { - int r, r2, size; - Sym *sym; -@@ -906,76 +902,76 @@ - - ushort_type.t = VT_SHORT | VT_UNSIGNED; - -- gv(RC_FLOAT); -+ gv(st, RC_FLOAT); - if (t != VT_INT) - size = 8; - else - size = 4; - -- o(0x2dd9); /* ldcw xxx */ -- sym = external_global_sym(TOK___tcc_int_fpu_control, -+ o(st, 0x2dd9); /* ldcw xxx */ -+ sym = external_global_sym(st, TOK___tcc_int_fpu_control, - &ushort_type, VT_LVAL); -- greloc(cur_text_section, sym, -+ greloc(st, cur_text_section, sym, - ind, R_386_32); -- gen_le32(0); -+ gen_le32(st, 0); - -- oad(0xec81, size); /* sub $xxx, %esp */ -+ oad(st, 0xec81, size); /* sub $xxx, %esp */ - if (size == 4) -- o(0x1cdb); /* fistpl */ -+ o(st, 0x1cdb); /* fistpl */ - else -- o(0x3cdf); /* fistpll */ -- o(0x24); -- o(0x2dd9); /* ldcw xxx */ -- sym = external_global_sym(TOK___tcc_fpu_control, -+ o(st, 0x3cdf); /* fistpll */ -+ o(st, 0x24); -+ o(st, 0x2dd9); /* ldcw xxx */ -+ sym = external_global_sym(st, TOK___tcc_fpu_control, - &ushort_type, VT_LVAL); -- greloc(cur_text_section, sym, -+ greloc(st, cur_text_section, sym, - ind, R_386_32); -- gen_le32(0); -+ gen_le32(st, 0); - -- r = get_reg(RC_INT); -- o(0x58 + r); /* pop r */ -+ r = get_reg(st, RC_INT); -+ o(st, 0x58 + r); /* pop r */ - if (size == 8) { - if (t == VT_LLONG) { - vtop->r = r; /* mark reg as used */ -- r2 = get_reg(RC_INT); -- o(0x58 + r2); /* pop r2 */ -+ r2 = get_reg(st, RC_INT); -+ o(st, 0x58 + r2); /* pop r2 */ - vtop->r2 = r2; - } else { -- o(0x04c483); /* add $4, %esp */ -+ o(st, 0x04c483); /* add $4, %esp */ - } - } - vtop->r = r; - } - - /* convert from one floating point type to another */ --void gen_cvt_ftof(int t) -+void gen_cvt_ftof(TCCState *st, int t) - { - /* all we have to do on i386 is to put the float in a register */ -- gv(RC_FLOAT); -+ gv(st, RC_FLOAT); - } - - /* computed goto support */ --void ggoto(void) -+void ggoto(TCCState *st) - { -- gcall_or_jmp(1); -+ gcall_or_jmp(st, 1); - vtop--; - } - - /* bound check support functions */ --#ifdef CONFIG_TCC_BCHECK -+#if 0 - - /* generate a bounded pointer addition */ --void gen_bounded_ptr_add(void) -+void gen_bounded_ptr_add() - { - Sym *sym; - - /* prepare fast i386 function call (args in eax and edx) */ -- gv2(RC_EAX, RC_EDX); -+ gv2(st, RC_EAX, RC_EDX); - /* save all temporary registers */ - vtop -= 2; -- save_regs(0); -+ save_regs(st, 0); - /* do a fast function call */ -- sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0); -+ sym = external_global_sym(st, TOK___bound_ptr_add, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); -@@ -997,14 +993,14 @@ - - size = 0; - /* XXX: put that code in generic part of tcc */ -- if (!is_float(vtop->type.t)) { -+ if (!is_float(st, vtop->type.t)) { - if (vtop->r & VT_LVAL_BYTE) - size = 1; - else if (vtop->r & VT_LVAL_SHORT) - size = 2; - } - if (!size) -- size = type_size(&vtop->type, &align); -+ size = type_size(st, &vtop->type, &align); - switch(size) { - case 1: func = TOK___bound_ptr_indir1; break; - case 2: func = TOK___bound_ptr_indir2; break; -@@ -1021,7 +1017,7 @@ - /* patch relocation */ - /* XXX: find a better solution ? */ - rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul); -- sym = external_global_sym(func, &func_old_type, 0); -+ sym = external_global_sym(st, func, &func_old_type, 0); - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info)); ---- tcc-0.9.23/il-gen.c 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/il-gen.c 2007-11-07 10:04:32.000000000 -0500 -@@ -3,19 +3,7 @@ - * - * Copyright (c) 2002 Fabrice Bellard - * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * Licensed under LGPL v2.1, see file COPYING in this tarball. - */ - - /* number of available registers */ ---- tcc-0.9.24/libtcc1.c 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/c/libtcc1.c 2007-11-07 10:04:02.000000000 -0500 -@@ -107,7 +107,7 @@ - }; - - /* XXX: use gcc/tcc intrinsic ? */ --#if defined(__i386__) -+#if 1 - #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ - : "=r" ((USItype) (sh)), \ -@@ -399,7 +399,7 @@ - if (vv.s.high < 0) - vv.ll = __negdi2 (vv.ll); - -- __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w); -+ __udivmoddi4 (uu.ll, vv.ll, &w); - if (c) - w = __negdi2 (w); - return w; -@@ -428,7 +428,7 @@ - u.s.low = u.s.high >> (b - 32); - u.s.high = u.s.high >> 31; - } else if (b != 0) { -- u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b)); -+ u.s.low = ((unsigned)u.s.low >> b) | ((unsigned)u.s.high << (32 - b)); - u.s.high = u.s.high >> b; - } - return u.ll; -@@ -447,7 +447,7 @@ - u.s.low = (unsigned)u.s.high >> (b - 32); - u.s.high = 0; - } else if (b != 0) { -- u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b)); -+ u.s.low = ((unsigned)u.s.low >> b) | ((unsigned)u.s.high << (32 - b)); - u.s.high = (unsigned)u.s.high >> b; - } - return u.ll; -@@ -475,7 +475,7 @@ - #endif - } - --#if defined(__i386__) -+#if 1 - /* FPU control word for rounding to nearest mode */ - unsigned short __tcc_fpu_control = 0x137f; - /* FPU control word for round to zero mode for int conversion */ ---- tcc-0.9.23/Makefile 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/Makefile 2007-11-07 10:04:32.000000000 -0500 -@@ -3,20 +3,21 @@ - # - include config.mak - --CFLAGS=-O2 -g -Wall -+CFLAGS+=-g -Wall -fsigned-char -Os - ifndef CONFIG_WIN32 --LIBS=-ldl -+LIBS=-lm -+ifndef CONFIG_NOLDL -+LIBS+=-ldl -+endif - BCHECK_O=bcheck.o - endif - CFLAGS_P=$(CFLAGS) -pg -static -DCONFIG_TCC_STATIC - LIBS_P= - --CFLAGS+=-mpreferred-stack-boundary=2 --ifeq ($(GCC_MAJOR),2) --CFLAGS+=-m386 -malign-functions=0 --else --CFLAGS+=-march=i386 -falign-functions=0 -fno-strict-aliasing --endif -+#CFLAGS+=-mpreferred-stack-boundary=2 -falign-functions=0 -+#ifneq ($(GCC_MAJOR),2) -+CFLAGS+=-fno-strict-aliasing -+#endif - - DISAS=objdump -d - INSTALL=install -@@ -46,11 +47,10 @@ - endif - - # run local version of tcc with local libraries and includes --TCC=./tcc -B. -I. -+TCC=./tcc -B. -I./include -I. - --all: $(PROGS) \ -- libtcc1.a $(BCHECK_O) tcc-doc.html tcc.1 libtcc.a \ -- libtcc_test$(EXESUF) -+all: $(PROGS) libtcc1.a $(BCHECK_O) libtcc.a libtcc_test$(EXESUF) \ -+ tcc-doc.html tcc.1 - - Makefile: config.mak - -@@ -59,45 +59,45 @@ - test: test.ref test.out - @if diff -u test.ref test.out ; then echo "Auto Test OK"; fi - --tcctest.ref: tcctest.c -- $(CC) $(CFLAGS) -I. -o $@ $< -+tcctest.ref: tests/tcctest.c -+ $(CC) $(CFLAGS) -I. -Iinclude -o $@ $< - - test.ref: tcctest.ref - ./tcctest.ref > $@ - --test.out: tcc tcctest.c -- $(TCC) -run tcctest.c > $@ -+test.out: tcc libtcc1.a tests/tcctest.c -+ $(TCC) -run tests/tcctest.c > $@ - --run: tcc tcctest.c -- $(TCC) -run tcctest.c -+run: tcc tests/tcctest.c -+ $(TCC) -run tests/tcctest.c - - # iterated test2 (compile tcc then compile tcctest.c !) --test2: tcc tcc.c tcctest.c test.ref -- $(TCC) -run tcc.c -B. -I. -run tcctest.c > test.out2 -+test2: tcc tcc.c tests/tcctest.c test.ref -+ $(TCC) -run tcc.c -B. -I. -run tests/tcctest.c > test.out2 - @if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi - - # iterated test3 (compile tcc then compile tcc then compile tcctest.c !) --test3: tcc tcc.c tcctest.c test.ref -- $(TCC) -run tcc.c -B. -I. -run tcc.c -B. -I. -run tcctest.c > test.out3 -+test3: tcc tcc.c tests/tcctest.c test.ref -+ $(TCC) -run tcc.c -B. -I. -run tcc.c -B. -I. -run tests/tcctest.c > test.out3 - @if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi - - # binary output test - test4: tcc test.ref - # dynamic output -- $(TCC) -o tcctest1 tcctest.c -+ $(TCC) -o tcctest1 tests/tcctest.c - ./tcctest1 > test1.out - @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi - # static output -- $(TCC) -static -o tcctest2 tcctest.c -+ $(TCC) -static -o tcctest2 tests/tcctest.c - ./tcctest2 > test2.out - @if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi - # object + link output -- $(TCC) -c -o tcctest3.o tcctest.c -+ $(TCC) -c -o tcctest3.o tests/tcctest.c - $(TCC) -o tcctest3 tcctest3.o - ./tcctest3 > test3.out - @if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi - # dynamic output + bound check -- $(TCC) -b -o tcctest4 tcctest.c -+ $(TCC) -b -o tcctest4 tests/tcctest.c - ./tcctest4 > test4.out - @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi - -@@ -137,11 +137,11 @@ - - # Host Tiny C Compiler - ifdef CONFIG_WIN32 --tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h tccpe.c -+tcc$(EXESUF): tcc.c i386/* tccelf.c tccasm.c tcctok.h libtcc.h win32/tccpe.c - $(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS) - else - ifeq ($(ARCH),i386) --tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h -+tcc$(EXESUF): tcc.c i386/* tccelf.c tccasm.c tcctok.h libtcc.h - $(CC) $(CFLAGS) -o $@ $< $(LIBS) - endif - ifeq ($(ARCH),arm) -@@ -151,20 +151,20 @@ - endif - - # Cross Tiny C Compilers --i386-tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h -+i386-tcc$(EXESUF): tcc.c i386/* tccelf.c tccasm.c tcctok.h libtcc.h - $(CC) $(CFLAGS) -o $@ $< $(LIBS) - - c67-tcc$(EXESUF): tcc.c c67-gen.c tccelf.c tccasm.c tcctok.h libtcc.h tcccoff.c - $(CC) $(CFLAGS) -DTCC_TARGET_C67 -o $@ $< $(LIBS) - - arm-tcc$(EXESUF): tcc.c arm-gen.c tccelf.c tccasm.c tcctok.h libtcc.h -- $(CC) $(CFLAGS) -DTCC_TARGET_ARM -o $@ $< $(LIBS) -+ $(CC) $(CFLAGS) -DTCC_TARGET_ARM -DTCC_ARM_EABI -o $@ $< $(LIBS) - --i386-win32-tcc$(EXESUF): tcc.c i386-gen.c tccelf.c tccasm.c i386-asm.c tcctok.h libtcc.h i386-asm.h tccpe.c -+i386-win32-tcc$(EXESUF): tcc.c i386/* tccelf.c tccasm.c tcctok.h libtcc.h win32/tccpe.c - $(CC) $(CFLAGS) -DTCC_TARGET_PE -o $@ $< $(LIBS) - - # windows utilities --tiny_impdef$(EXESUF): tiny_impdef.c -+tiny_impdef$(EXESUF): win32/tiny_impdef.c - $(CC) $(CFLAGS) -o $@ $< -lkernel32 - - # TinyCC runtime libraries -@@ -174,6 +174,9 @@ - LIBTCC1_CC=./tcc.exe -Bwin32 - else - LIBTCC1_OBJS=libtcc1.o -+ifeq ($(ARCH),i386) -+LIBTCC1_OBJS+=i386/alloca86.o i386/bound-alloca86.o -+endif - LIBTCC1_CC=$(CC) - endif - -@@ -191,12 +194,12 @@ - - install: tcc_install libinstall - --tcc_install: $(PROGS) tcc.1 libtcc1.a $(BCHECK_O) tcc-doc.html tcc.1 -+tcc_install: $(PROGS) libtcc1.a $(BCHECK_O) tcc-doc.html tcc.1 - mkdir -p "$(bindir)" - $(INSTALL) -s -m755 $(PROGS) "$(bindir)" - ifndef CONFIG_WIN32 - mkdir -p "$(mandir)/man1" -- $(INSTALL) tcc.1 "$(mandir)/man1" -+ -$(INSTALL) tcc.1 "$(mandir)/man1" - endif - mkdir -p "$(tccdir)" - mkdir -p "$(tccdir)/include" -@@ -207,19 +210,18 @@ - cp -r win32/examples/. "$(tccdir)/examples" - else - $(INSTALL) -m644 libtcc1.a $(BCHECK_O) "$(tccdir)" -- $(INSTALL) -m644 stdarg.h stddef.h stdbool.h float.h varargs.h \ -- tcclib.h "$(tccdir)/include" -+ $(INSTALL) -m644 include/* "$(tccdir)/include" - endif - mkdir -p "$(docdir)" -- $(INSTALL) -m644 tcc-doc.html "$(docdir)" -+ -$(INSTALL) -m644 tcc-doc.html "$(docdir)" - ifdef CONFIG_WIN32 - $(INSTALL) -m644 win32/readme.txt "$(docdir)" - endif - - clean: -- rm -f *~ *.o *.a tcc tcc1 tcct tcc_g tcctest.ref *.bin *.i ex2 \ -+ rm -f *~ *.o *.a tcc tcc.1 tcct tcc_g tcctest.ref *.bin *.i ex2 \ - core gmon.out test.out test.ref a.out tcc_p \ -- *.exe *.lib tcc.pod libtcc_test \ -+ *.exe *.lib tcc.pod libtcc_test i386/*.o \ - tcctest[1234] test[1234].out $(PROGS) win32/lib/*.o - - distclean: clean -@@ -236,13 +238,13 @@ - mkdir -p "$(includedir)" - $(INSTALL) -m644 libtcc.h "$(includedir)" - --libtcc.o: tcc.c i386-gen.c Makefile -+libtcc.o: tcc.c i386/i386-gen.c Makefile - $(CC) $(CFLAGS) -DLIBTCC -c -o $@ $< - - libtcc.a: libtcc.o - $(AR) rcs $@ $^ - --libtcc_test$(EXESUF): libtcc_test.c libtcc.a -+libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a - $(CC) $(CFLAGS) -o $@ $< libtcc.a $(LIBS) - - libtest: libtcc_test -@@ -282,11 +284,11 @@ - - # documentation and man page - tcc-doc.html: tcc-doc.texi -- texi2html -monolithic -number $< -+ -texi2html -monolithic -number $< - - tcc.1: tcc-doc.texi -- ./texi2pod.pl $< tcc.pod -- pod2man --section=1 --center=" " --release=" " tcc.pod > $@ -+ -./texi2pod.pl $< tcc.pod -+ -pod2man --section=1 --center=" " --release=" " tcc.pod > $@ - - FILE=tcc-$(shell cat VERSION) - -@@ -294,5 +296,5 @@ - tar: - rm -rf /tmp/$(FILE) - cp -r . /tmp/$(FILE) -- ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS ) -+ ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude .hg ) - rm -rf /tmp/$(FILE) ---- tcc-0.9.24/README 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/demo/expat/README 2007-11-07 10:04:16.000000000 -0500 -@@ -1,91 +1,137 @@ --Tiny C Compiler - C Scripting Everywhere - The Smallest ANSI C compiler ------------------------------------------------------------------------- - --Features: ---------- -+ Expat, Release 2.0.1 - --- SMALL! You can compile and execute C code everywhere, for example on -- rescue disks. -+This is Expat, a C library for parsing XML, written by James Clark. -+Expat is a stream-oriented XML parser. This means that you register -+handlers with the parser before starting the parse. These handlers -+are called when the parser discovers the associated structures in the -+document being parsed. A start tag is an example of the kind of -+structures for which you may register handlers. -+ -+Windows users should use the expat_win32bin package, which includes -+both precompiled libraries and executables, and source code for -+developers. -+ -+Expat is free software. You may copy, distribute, and modify it under -+the terms of the License contained in the file COPYING distributed -+with this package. This license is the same as the MIT/X Consortium -+license. -+ -+Versions of Expat that have an odd minor version (the middle number in -+the release above), are development releases and should be considered -+as beta software. Releases with even minor version numbers are -+intended to be production grade software. -+ -+If you are building Expat from a check-out from the CVS repository, -+you need to run a script that generates the configure script using the -+GNU autoconf and libtool tools. To do this, you need to have -+autoconf 2.52 or newer and libtool 1.4 or newer (1.5 or newer preferred). -+Run the script like this: - --- FAST! tcc generates optimized x86 code. No byte code -- overhead. Compile, assemble and link about 7 times faster than 'gcc -- -O0'. -+ ./buildconf.sh - --- UNLIMITED! Any C dynamic library can be used directly. TCC is -- heading torward full ISOC99 compliance. TCC can of course compile -- itself. -+Once this has been done, follow the same instructions as for building -+from a source distribution. - --- SAFE! tcc includes an optional memory and bound checker. Bound -- checked code can be mixed freely with standard code. -+To build Expat from a source distribution, you first run the -+configuration shell script in the top level distribution directory: - --- Compile and execute C source directly. No linking or assembly -- necessary. Full C preprocessor included. -+ ./configure - --- C script supported : just add '#!/usr/local/bin/tcc -run' at the first -- line of your C source, and execute it directly from the command -- line. -+There are many options which you may provide to configure (which you -+can discover by running configure with the --help option). But the -+one of most interest is the one that sets the installation directory. -+By default, the configure script will set things up to install -+libexpat into /usr/local/lib, expat.h into /usr/local/include, and -+xmlwf into /usr/local/bin. If, for example, you'd prefer to install -+into /home/me/mystuff/lib, /home/me/mystuff/include, and -+/home/me/mystuff/bin, you can tell configure about that with: - --Documentation: --------------- -+ ./configure --prefix=/home/me/mystuff - --1) Installation on a i386 Linux host (for Windows read win32/readme.txt) -+Another interesting option is to enable 64-bit integer support for -+line and column numbers and the over-all byte index: - -- ./configure -- make -- make test -- make install -+ ./configure CPPFLAGS=-DXML_LARGE_SIZE -+ -+However, such a modification would be a breaking change to the ABI -+and is therefore not recommended for general use - e.g. as part of -+a Linux distribution - but rather for builds with special requirements. -+ -+After running the configure script, the "make" command will build -+things and "make install" will install things into their proper -+location. Have a look at the "Makefile" to learn about additional -+"make" options. Note that you need to have write permission into -+the directories into which things will be installed. - --By default, tcc is installed in /usr/local/bin. --./configure --help shows configuration options. -+If you are interested in building Expat to provide document -+information in UTF-16 rather than the default UTF-8, follow these -+instructions (after having run "make distclean"): - -+ 1. For UTF-16 output as unsigned short (and version/error -+ strings as char), run: - --2) Introduction -+ ./configure CPPFLAGS=-DXML_UNICODE - --We assume here that you know ANSI C. Look at the example ex1.c to know --what the programs look like. -+ For UTF-16 output as wchar_t (incl. version/error strings), -+ run: - --The include file can be used if you want a small basic libc --include support (especially useful for floppy disks). Of course, you --can also use standard headers, although they are slower to compile. -+ ./configure CFLAGS="-g -O2 -fshort-wchar" \ -+ CPPFLAGS=-DXML_UNICODE_WCHAR_T - --You can begin your C script with '#!/usr/local/bin/tcc -run' on the first --line and set its execute bits (chmod a+x your_script). Then, you can --launch the C code as a shell or perl script :-) The command line --arguments are put in 'argc' and 'argv' of the main functions, as in --ANSI C. -+ 2. Edit the MakeFile, changing: - --3) Examples -+ LIBRARY = libexpat.la - --ex1.c: simplest example (hello world). Can also be launched directly --as a script: './ex1.c'. -+ to: - --ex2.c: more complicated example: find a number with the four --operations given a list of numbers (benchmark). -+ LIBRARY = libexpatw.la - --ex3.c: compute fibonacci numbers (benchmark). -+ (Note the additional "w" in the library name.) - --ex4.c: more complicated: X11 program. Very complicated test in fact --because standard headers are being used ! -+ 3. Run "make buildlib" (which builds the library only). -+ Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la". - --ex5.c: 'hello world' with standard glibc headers. -+ 4. Run "make installlib" (which installs the library only). -+ Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la". - --tcc.c: TCC can of course compile itself. Used to check the code --generator. -+Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default -+value for DESTDIR, and the rest of the make file using only DESTDIR. -+It works as follows: -+ $ make install DESTDIR=/path/to/image -+overrides the in-makefile set DESTDIR, while both -+ $ INSTALL_ROOT=/path/to/image make install -+ $ make install INSTALL_ROOT=/path/to/image -+use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the -+environment, because variable-setting priority is -+1) commandline -+2) in-makefile -+3) environment - --tcctest.c: auto test for TCC which tests many subtle possible bugs. Used --when doing 'make test'. -+Note for Solaris users: The "ar" command is usually located in -+"/usr/ccs/bin", which is not in the default PATH. You will need to -+add this to your path for the "make" command, and probably also switch -+to GNU make (the "make" found in /usr/ccs/bin does not seem to work -+properly -- appearantly it does not understand .PHONY directives). If -+you're using ksh or bash, use this command to build: - --4) Full Documentation -+ PATH=/usr/ccs/bin:$PATH make - --Please read tcc-doc.html to have all the features of TCC. -+When using Expat with a project using autoconf for configuration, you -+can use the probing macro in conftools/expat.m4 to determine how to -+include Expat. See the comments at the top of that file for more -+information. - --Additional information is available for the Windows port in --win32/readme.txt. -+A reference manual is available in the file doc/reference.html in this -+distribution. - --License: --------- -+The homepage for this project is http://www.libexpat.org/. There -+are links there to connect you to the bug reports page. If you need -+to report a bug when you don't have access to a browser, you may also -+send a bug report by email to expat-bugs@mail.libexpat.org. - --TCC is distributed under the GNU Lesser General Public License (see --COPYING file). -+Discussion related to the direction of future expat development takes -+place on expat-discuss@mail.libexpat.org. Archives of this list and -+other Expat-related lists may be found at: - --Fabrice Bellard. -+ http://mail.libexpat.org/mailman/listinfo/ ---- tcc-0.9.23/tcc.1 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/tcc.1 2007-11-07 10:04:32.000000000 -0500 -@@ -1,7 +1,8 @@ --.\" Automatically generated by Pod::Man v1.34, Pod::Parser v1.13 -+.\" Automatically generated by Pod::Man version 1.15 -+.\" Fri Oct 5 16:48:47 2007 - .\" - .\" Standard preamble: --.\" ======================================================================== -+.\" ====================================================================== - .de Sh \" Subsection heading - .br - .if t .Sp -@@ -14,6 +15,12 @@ - .if t .sp .5v - .if n .sp - .. -+.de Ip \" List item -+.br -+.ie \\n(.$>=3 .ne \\$3 -+.el .ne 3 -+.IP "\\$1" \\$2 -+.. - .de Vb \" Begin verbatim text - .ft CW - .nf -@@ -21,14 +28,15 @@ - .. - .de Ve \" End verbatim text - .ft R -+ - .fi - .. - .\" Set up some character translations and predefined strings. \*(-- will - .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left - .\" double quote, and \*(R" will give a right double quote. | will give a --.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to --.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' --.\" expand to `' in nroff, nothing in troff, for use with C<>. -+.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used -+.\" to do unbreakable dashes and therefore won't be available. \*(C` and -+.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<> - .tr \(*W-|\(bv\*(Tr - .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' - .ie n \{\ -@@ -48,10 +56,10 @@ - . ds R" '' - 'br\} - .\" --.\" If the F register is turned on, we'll generate index entries on stderr for --.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index --.\" entries marked with X<> in POD. Of course, you'll have to process the --.\" output yourself in some meaningful fashion. -+.\" If the F register is turned on, we'll generate index entries on stderr -+.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and -+.\" index entries marked with X<> in POD. Of course, you'll have to process -+.\" the output yourself in some meaningful fashion. - .if \nF \{\ - . de IX - . tm Index:\\$1\t\\n%\t"\\$2" -@@ -60,13 +68,14 @@ - . rr F - .\} - .\" --.\" For nroff, turn off justification. Always turn off hyphenation; it makes --.\" way too many mistakes in technical documents. -+.\" For nroff, turn off justification. Always turn off hyphenation; it -+.\" makes way too many mistakes in technical documents. - .hy 0 - .if n .na - .\" - .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). - .\" Fear. Run. Save yourself. No user-serviceable parts. -+.bd B 3 - . \" fudge factors for nroff and troff - .if n \{\ - . ds #H 0 -@@ -126,10 +135,11 @@ - . ds Ae AE - .\} - .rm #[ #] #H #V #F C --.\" ======================================================================== -+.\" ====================================================================== - .\" - .IX Title "TCC 1" --.TH TCC 1 "2005-06-18" " " " " -+.TH TCC 1 " " "2007-10-05" " " -+.UC - .SH "NAME" - tcc \- Tiny C Compiler - .SH "SYNOPSIS" -@@ -142,59 +152,58 @@ - arguments. - .PP - Here are some examples to understand the logic: --.ie n .IP """\f(CBtcc \-run a.c\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-run a.c\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-run a.c\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-run a.c\f(CW\fR" 4 - .IX Item "tcc -run a.c" - Compile \fIa.c\fR and execute it directly --.ie n .IP """\f(CBtcc \-run a.c arg1\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-run a.c arg1\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-run a.c arg1\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-run a.c arg1\f(CW\fR" 4 - .IX Item "tcc -run a.c arg1" - Compile a.c and execute it directly. arg1 is given as first argument to - the \f(CW\*(C`main()\*(C'\fR of a.c. --.ie n .IP """\f(CBtcc a.c \-run b.c arg1\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc a.c \-run b.c arg1\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc a.c \-run b.c arg1\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc a.c \-run b.c arg1\f(CW\fR" 4 - .IX Item "tcc a.c -run b.c arg1" - Compile \fIa.c\fR and \fIb.c\fR, link them together and execute them. arg1 is given - as first argument to the \f(CW\*(C`main()\*(C'\fR of the resulting program. Because --multiple C files are specified, \fB\-\-\fR are necessary to clearly separate the -+multiple C files are specified, \fB\--\fR are necessary to clearly separate the - program arguments from the \s-1TCC\s0 options. --.ie n .IP """\f(CBtcc \-o myprog a.c b.c\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-o myprog a.c b.c\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-o myprog a.c b.c\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-o myprog a.c b.c\f(CW\fR" 4 - .IX Item "tcc -o myprog a.c b.c" - Compile \fIa.c\fR and \fIb.c\fR, link them and generate the executable \fImyprog\fR. --.ie n .IP """\f(CBtcc \-o myprog a.o b.o\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-o myprog a.o b.o\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-o myprog a.o b.o\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-o myprog a.o b.o\f(CW\fR" 4 - .IX Item "tcc -o myprog a.o b.o" - link \fIa.o\fR and \fIb.o\fR together and generate the executable \fImyprog\fR. --.ie n .IP """\f(CBtcc \-c a.c\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-c a.c\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-c a.c\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-c a.c\f(CW\fR" 4 - .IX Item "tcc -c a.c" - Compile \fIa.c\fR and generate object file \fIa.o\fR. --.ie n .IP """\f(CBtcc \-c asmfile.S\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-c asmfile.S\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-c asmfile.S\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-c asmfile.S\f(CW\fR" 4 - .IX Item "tcc -c asmfile.S" - Preprocess with C preprocess and assemble \fIasmfile.S\fR and generate - object file \fIasmfile.o\fR. --.ie n .IP """\f(CBtcc \-c asmfile.s\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-c asmfile.s\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-c asmfile.s\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-c asmfile.s\f(CW\fR" 4 - .IX Item "tcc -c asmfile.s" - Assemble (but not preprocess) \fIasmfile.s\fR and generate object file - \&\fIasmfile.o\fR. --.ie n .IP """\f(CBtcc \-r \-o ab.o a.c b.c\f(CW""" 4 --.el .IP "\f(CW\f(CBtcc \-r \-o ab.o a.c b.c\f(CW\fR" 4 -+.if n .Ip "\f(CW""""\f(CBtcc \-r \-o ab.o a.c b.c\f(CW""""\fR" 4 -+.el .Ip "\f(CW\f(CBtcc \-r \-o ab.o a.c b.c\f(CW\fR" 4 - .IX Item "tcc -r -o ab.o a.c b.c" - Compile \fIa.c\fR and \fIb.c\fR, link them together and generate the object file \fIab.o\fR. - .PP - Scripting: - .PP - \&\s-1TCC\s0 can be invoked from \fIscripts\fR, just as shell scripts. You just --need to add \f(CW\*(C`#!/usr/local/bin/tcc \-run\*(C'\fR at the start of your C source: -+need to add \f(CW\*(C`#!/usr/bin/tcc \-run\*(C'\fR at the start of your C source: - .PP - .Vb 2 --\& #!/usr/local/bin/tcc -run -+\& #!/usr/bin/tcc -run - \& #include - .Ve --.PP - .Vb 5 - \& int main() - \& { -@@ -204,23 +213,23 @@ - .Ve - .SH "OPTIONS" - .IX Header "OPTIONS" --.IP "\fB\-v\fR" 4 -+.Ip "\fB\-v\fR" 4 - .IX Item "-v" - Display current \s-1TCC\s0 version. --.IP "\fB\-c\fR" 4 -+.Ip "\fB\-c\fR" 4 - .IX Item "-c" - Generate an object file (\fB\-o\fR option must also be given). --.IP "\fB\-o outfile\fR" 4 -+.Ip "\fB\-o outfile\fR" 4 - .IX Item "-o outfile" - Put object file, executable, or dll into output file \fIoutfile\fR. --.IP "\fB\-Bdir\fR" 4 -+.Ip "\fB\-Bdir\fR" 4 - .IX Item "-Bdir" - Set the path where the tcc internal libraries can be found (default is - \&\fIPREFIX/lib/tcc\fR). --.IP "\fB\-bench\fR" 4 -+.Ip "\fB\-bench\fR" 4 - .IX Item "-bench" - Output compilation statistics. --.IP "\fB\-run source [args...]\fR" 4 -+.Ip "\fB\-run source [args...]\fR" 4 - .IX Item "-run source [args...]" - Compile file \fIsource\fR and run it with the command line arguments - \&\fIargs\fR. In order to be able to give more than one argument to a -@@ -230,11 +239,10 @@ - .Vb 1 - \& tcc "-run -L/usr/X11R6/lib -lX11" ex4.c - .Ve --.Sp - In a script, it gives the following header: - .Sp - .Vb 6 --\& #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 -+\& #!/usr/bin/tcc -run -L/usr/X11R6/lib -lX11 - \& #include - \& int main(int argc, char **argv) - \& { -@@ -243,7 +251,7 @@ - .Ve - .PP - Preprocessor options: --.IP "\fB\-Idir\fR" 4 -+.Ip "\fB\-Idir\fR" 4 - .IX Item "-Idir" - Specify an additional include path. Include paths are searched in the - order they are specified. -@@ -252,100 +260,100 @@ - include paths are: \fI/usr/local/include\fR, \fI/usr/include\fR - and \fIPREFIX/lib/tcc/include\fR. (\fI\s-1PREFIX\s0\fR is usually - \&\fI/usr\fR or \fI/usr/local\fR). --.IP "\fB\-Dsym[=val]\fR" 4 -+.Ip "\fB\-Dsym[=val]\fR" 4 - .IX Item "-Dsym[=val]" - Define preprocessor symbol \fBsym\fR to - val. If val is not present, its value is \fB1\fR. Function-like macros can --also be defined: \fB\-DF(a)=a+1\fR --.IP "\fB\-Usym\fR" 4 -+also be defined: \fB\-\f(BIDF\fB\|(a)=a+1\fR -+.Ip "\fB\-Usym\fR" 4 - .IX Item "-Usym" - Undefine preprocessor symbol \fBsym\fR. - .PP - Compilation flags: - .PP - Note: each of the following warning options has a negative form beginning with --\&\fB\-fno\-\fR. --.IP "\fB\-funsigned\-char\fR" 4 -+\&\fB\-fno-\fR. -+.Ip "\fB\-funsigned-char\fR" 4 - .IX Item "-funsigned-char" - Let the \f(CW\*(C`char\*(C'\fR type be unsigned. --.IP "\fB\-fsigned\-char\fR" 4 -+.Ip "\fB\-fsigned-char\fR" 4 - .IX Item "-fsigned-char" - Let the \f(CW\*(C`char\*(C'\fR type be signed. --.IP "\fB\-fno\-common\fR" 4 -+.Ip "\fB\-fno-common\fR" 4 - .IX Item "-fno-common" - Do not generate common symbols for uninitialized data. --.IP "\fB\-fleading\-underscore\fR" 4 -+.Ip "\fB\-fleading-underscore\fR" 4 - .IX Item "-fleading-underscore" - Add a leading underscore at the beginning of each C symbol. - .PP - Warning options: --.IP "\fB\-w\fR" 4 -+.Ip "\fB\-w\fR" 4 - .IX Item "-w" - Disable all warnings. - .PP - Note: each of the following warning options has a negative form beginning with --\&\fB\-Wno\-\fR. --.IP "\fB\-Wimplicit\-function\-declaration\fR" 4 -+\&\fB\-Wno-\fR. -+.Ip "\fB\-Wimplicit-function-declaration\fR" 4 - .IX Item "-Wimplicit-function-declaration" - Warn about implicit function declaration. --.IP "\fB\-Wunsupported\fR" 4 -+.Ip "\fB\-Wunsupported\fR" 4 - .IX Item "-Wunsupported" - Warn about unsupported \s-1GCC\s0 features that are ignored by \s-1TCC\s0. --.IP "\fB\-Wwrite\-strings\fR" 4 -+.Ip "\fB\-Wwrite-strings\fR" 4 - .IX Item "-Wwrite-strings" - Make string constants be of type \f(CW\*(C`const char *\*(C'\fR instead of \f(CW\*(C`char - *\*(C'\fR. --.IP "\fB\-Werror\fR" 4 -+.Ip "\fB\-Werror\fR" 4 - .IX Item "-Werror" - Abort compilation if warnings are issued. --.IP "\fB\-Wall\fR" 4 -+.Ip "\fB\-Wall\fR" 4 - .IX Item "-Wall" - Activate all warnings, except \fB\-Werror\fR, \fB\-Wunusupported\fR and --\&\fB\-Wwrite\-strings\fR. -+\&\fB\-Wwrite-strings\fR. - .PP - Linker options: --.IP "\fB\-Ldir\fR" 4 -+.Ip "\fB\-Ldir\fR" 4 - .IX Item "-Ldir" - Specify an additional static library path for the \fB\-l\fR option. The - default library paths are \fI/usr/local/lib\fR, \fI/usr/lib\fR and \fI/lib\fR. --.IP "\fB\-lxxx\fR" 4 -+.Ip "\fB\-lxxx\fR" 4 - .IX Item "-lxxx" - Link your program with dynamic library libxxx.so or static library - libxxx.a. The library is searched in the paths specified by the - \&\fB\-L\fR option. --.IP "\fB\-shared\fR" 4 -+.Ip "\fB\-shared\fR" 4 - .IX Item "-shared" - Generate a shared library instead of an executable (\fB\-o\fR option - must also be given). --.IP "\fB\-static\fR" 4 -+.Ip "\fB\-static\fR" 4 - .IX Item "-static" - Generate a statically linked executable (default is a shared linked - executable) (\fB\-o\fR option must also be given). --.IP "\fB\-rdynamic\fR" 4 -+.Ip "\fB\-rdynamic\fR" 4 - .IX Item "-rdynamic" - Export global symbols to the dynamic linker. It is useful when a library - opened with \f(CW\*(C`dlopen()\*(C'\fR needs to access executable symbols. --.IP "\fB\-r\fR" 4 -+.Ip "\fB\-r\fR" 4 - .IX Item "-r" - Generate an object file combining all input files (\fB\-o\fR option must - also be given). --.IP "\fB\-Wl,\-Ttext,address\fR" 4 -+.Ip "\fB\-Wl,\-Ttext,address\fR" 4 - .IX Item "-Wl,-Ttext,address" - Set the start of the .text section to \fIaddress\fR. --.IP "\fB\-Wl,\-\-oformat,fmt\fR" 4 -+.Ip "\fB\-Wl,\-\-oformat,fmt\fR" 4 - .IX Item "-Wl,--oformat,fmt" - Use \fIfmt\fR as output format. The supported output formats are: - .RS 4 --.ie n .IP """elf32\-i386""" 4 --.el .IP "\f(CWelf32\-i386\fR" 4 -+.if n .Ip "\f(CW""""elf32\-i386""""\fR" 4 -+.el .Ip "\f(CWelf32\-i386\fR" 4 - .IX Item "elf32-i386" - \&\s-1ELF\s0 output format (default) --.ie n .IP """binary""" 4 --.el .IP "\f(CWbinary\fR" 4 -+.if n .Ip "\f(CW""""binary""""\fR" 4 -+.el .Ip "\f(CWbinary\fR" 4 - .IX Item "binary" - Binary image (only for executable output) --.ie n .IP """coff""" 4 --.el .IP "\f(CWcoff\fR" 4 -+.if n .Ip "\f(CW""""coff""""\fR" 4 -+.el .Ip "\f(CWcoff\fR" 4 - .IX Item "coff" - \&\s-1COFF\s0 output format (only for executable output for TMS320C67xx target) - .RE -@@ -353,18 +361,18 @@ - .RE - .PP - Debugger options: --.IP "\fB\-g\fR" 4 -+.Ip "\fB\-g\fR" 4 - .IX Item "-g" - Generate run time debug information so that you get clear run time - error messages: \f(CW\*(C` test.c:68: in function 'test5()': dereferencing - invalid pointer\*(C'\fR instead of the laconic \f(CW\*(C`Segmentation - fault\*(C'\fR. --.IP "\fB\-b\fR" 4 -+.Ip "\fB\-b\fR" 4 - .IX Item "-b" - Generate additional support code to check - memory allocations and array/pointer bounds. \fB\-g\fR is implied. Note - that the generated code is slower and bigger in this case. --.IP "\fB\-bt N\fR" 4 -+.Ip "\fB\-bt N\fR" 4 - .IX Item "-bt N" - Display N callers in stack traces. This is useful with \fB\-g\fR or - \&\fB\-b\fR. ---- tcc-0.9.24/tccasm.c 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/tccasm.c 2007-11-07 10:04:32.000000000 -0500 -@@ -24,7 +24,7 @@ - TokenSym *ts; - - snprintf(buf, sizeof(buf), "L..%u", n); -- ts = tok_alloc(buf, strlen(buf)); -+ ts = tok_alloc(s1, buf, strlen(buf)); - return ts->tok; - } - -@@ -46,18 +46,18 @@ - if (*p == 'b' || *p == 'f') { - /* backward or forward label */ - label = asm_get_local_label_name(s1, n); -- sym = label_find(label); -+ sym = label_find(s1, label); - if (*p == 'b') { - /* backward : find the last corresponding defined label */ - if (sym && sym->r == 0) - sym = sym->prev_tok; - if (!sym) -- error("local label '%d' not found backward", n); -+ tcc_error(s1, "local label '%d' not found backward", n); - } else { - /* forward */ - if (!sym || sym->r) { - /* if the last label is defined, then define a new one */ -- sym = label_push(&s1->asm_labels, label, 0); -+ sym = label_push(s1, &s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; - } - } -@@ -67,21 +67,21 @@ - pe->v = n; - pe->sym = NULL; - } else { -- error("invalid number syntax"); -+ tcc_error(s1, "invalid number syntax"); - } -- next(); -+ next(s1); - break; - case '+': -- next(); -+ next(s1); - asm_expr_unary(s1, pe); - break; - case '-': - case '~': - op = tok; -- next(); -+ next(s1); - asm_expr_unary(s1, pe); - if (pe->sym) -- error("invalid operation with label"); -+ tcc_error(s1, "invalid operation with label"); - if (op == '-') - pe->v = -pe->v; - else -@@ -91,19 +91,19 @@ - case TOK_LCHAR: - pe->v = tokc.i; - pe->sym = NULL; -- next(); -+ next(s1); - break; - case '(': -- next(); -+ next(s1); - asm_expr(s1, pe); -- skip(')'); -+ skip(s1, ')'); - break; - default: - if (tok >= TOK_IDENT) { - /* label case : if the label was not found, add one */ -- sym = label_find(tok); -+ sym = label_find(s1, tok); - if (!sym) { -- sym = label_push(&s1->asm_labels, tok, 0); -+ sym = label_push(s1, &s1->asm_labels, tok, 0); - /* NOTE: by default, the symbol is global */ - sym->type.t = VT_VOID; - } -@@ -115,9 +115,9 @@ - pe->v = 0; - pe->sym = sym; - } -- next(); -+ next(s1); - } else { -- error("bad expression syntax [%s]", get_tok_str(tok, &tokc)); -+ tcc_error(s1, "bad expression syntax [%s]", get_tok_str(s1, tok, &tokc)); - } - break; - } -@@ -134,10 +134,10 @@ - if (op != '*' && op != '/' && op != '%' && - op != TOK_SHL && op != TOK_SAR) - break; -- next(); -+ next(s1); - asm_expr_unary(s1, &e2); - if (pe->sym || e2.sym) -- error("invalid operation with label"); -+ tcc_error(s1, "invalid operation with label"); - switch(op) { - case '*': - pe->v *= e2.v; -@@ -145,7 +145,7 @@ - case '/': - if (e2.v == 0) { - div_error: -- error("division by zero"); -+ tcc_error(s1, "division by zero"); - } - pe->v /= e2.v; - break; -@@ -175,10 +175,10 @@ - op = tok; - if (op != '&' && op != '|' && op != '^') - break; -- next(); -+ next(s1); - asm_expr_prod(s1, &e2); - if (pe->sym || e2.sym) -- error("invalid operation with label"); -+ tcc_error(s1, "invalid operation with label"); - switch(op) { - case '&': - pe->v &= e2.v; -@@ -204,7 +204,7 @@ - op = tok; - if (op != '+' && op != '-') - break; -- next(); -+ next(s1); - asm_expr_logic(s1, &e2); - if (op == '+') { - if (pe->sym != NULL && e2.sym != NULL) -@@ -232,7 +232,7 @@ - pe->sym = NULL; /* same symbols can be substracted to NULL */ - } else { - cannot_relocate: -- error("invalid operation with label"); -+ tcc_error(s1, "invalid operation with label"); - } - } - } -@@ -248,7 +248,7 @@ - ExprValue e; - asm_expr(s1, &e); - if (e.sym) -- expect("constant"); -+ expect(s1, "constant"); - return e.v; - } - -@@ -259,13 +259,13 @@ - { - Sym *sym; - -- sym = label_find(label); -+ sym = label_find(s1, label); - if (sym) { - if (sym->r) { - /* the label is already defined */ - if (!is_local) { -- error("assembler label '%s' already defined", -- get_tok_str(label, NULL)); -+ tcc_error(s1, "assembler label '%s' already defined", -+ get_tok_str(s1, label, NULL)); - } else { - /* redefinition of local labels is possible */ - goto new_label; -@@ -273,7 +273,7 @@ - } - } else { - new_label: -- sym = label_push(&s1->asm_labels, label, 0); -+ sym = label_push(s1, &s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; - } - sym->r = sh_num; -@@ -298,11 +298,11 @@ - sec = SECTION_ABS; - else - sec = st->sections[s->r]; -- put_extern_sym2(s, sec, (long)s->next, 0, 0); -+ put_extern_sym2(st, s, sec, (long)s->next, 0, 0); - } - /* remove label */ - table_ident[s->v - TOK_IDENT]->sym_label = NULL; -- sym_free(s); -+ sym_free(st,s); - } - st->asm_labels = NULL; - } -@@ -328,18 +328,18 @@ - uint8_t *ptr; - - /* assembler directive */ -- next(); -+ next(s1); - sec = cur_text_section; - switch(tok) { - case TOK_ASM_align: - case TOK_ASM_skip: - case TOK_ASM_space: - tok1 = tok; -- next(); -+ next(s1); - n = asm_int_expr(s1); - if (tok1 == TOK_ASM_align) { - if (n < 0 || (n & (n-1)) != 0) -- error("alignment must be a positive power of two"); -+ tcc_error(s1, "alignment must be a positive power of two"); - offset = (ind + n - 1) & -n; - size = offset - ind; - /* the section must have a compatible alignment */ -@@ -350,19 +350,19 @@ - } - v = 0; - if (tok == ',') { -- next(); -+ next(s1); - v = asm_int_expr(s1); - } - zero_pad: - if (sec->sh_type != SHT_NOBITS) { - sec->data_offset = ind; -- ptr = section_ptr_add(sec, size); -+ ptr = section_ptr_add(s1, sec, size); - memset(ptr, v, size); - } - ind += size; - break; - case TOK_ASM_quad: -- next(); -+ next(s1); - for(;;) { - uint64_t vl; - const char *p; -@@ -370,22 +370,22 @@ - p = tokc.cstr->data; - if (tok != TOK_PPNUM) { - error_constant: -- error("64 bit constant"); -+ tcc_error(s1, "64 bit constant"); - } - vl = strtoll(p, (char **)&p, 0); - if (*p != '\0') - goto error_constant; -- next(); -+ next(s1); - if (sec->sh_type != SHT_NOBITS) { - /* XXX: endianness */ -- gen_le32(vl); -- gen_le32(vl >> 32); -+ gen_le32(s1, vl); -+ gen_le32(s1, vl >> 32); - } else { - ind += 8; - } - if (tok != ',') - break; -- next(); -+ next(s1); - } - break; - case TOK_ASM_byte: -@@ -399,52 +399,52 @@ - case TOK_INT: - size = 4; - asm_data: -- next(); -+ next(s1); - for(;;) { - ExprValue e; - asm_expr(s1, &e); - if (sec->sh_type != SHT_NOBITS) { - if (size == 4) { -- gen_expr32(&e); -+ gen_expr32(s1, &e); - } else { - if (e.sym) -- expect("constant"); -+ expect(s1, "constant"); - if (size == 1) -- g(e.v); -+ g(s1, e.v); - else -- gen_le16(e.v); -+ gen_le16(s1, e.v); - } - } else { - ind += size; - } - if (tok != ',') - break; -- next(); -+ next(s1); - } - break; - case TOK_ASM_fill: - { - int repeat, size, val, i, j; - uint8_t repeat_buf[8]; -- next(); -+ next(s1); - repeat = asm_int_expr(s1); - if (repeat < 0) { -- error("repeat < 0; .fill ignored"); -+ tcc_error(s1, "repeat < 0; .fill ignored"); - break; - } - size = 1; - val = 0; - if (tok == ',') { -- next(); -+ next(s1); - size = asm_int_expr(s1); - if (size < 0) { -- error("size < 0; .fill ignored"); -+ tcc_error(s1, "size < 0; .fill ignored"); - break; - } - if (size > 8) - size = 8; - if (tok == ',') { -- next(); -+ next(s1); - val = asm_int_expr(s1); - } - } -@@ -459,7 +459,7 @@ - repeat_buf[7] = 0; - for(i = 0; i < repeat; i++) { - for(j = 0; j < size; j++) { -- g(repeat_buf[j]); -+ g(s1, repeat_buf[j]); - } - } - } -@@ -467,11 +467,11 @@ - case TOK_ASM_org: - { - unsigned long n; -- next(); -+ next(s1); - /* XXX: handle section symbols too */ - n = asm_int_expr(s1); - if (n < ind) -- error("attempt to .org backwards"); -+ tcc_error(s1, "attempt to .org backwards"); - v = 0; - size = n - ind; - goto zero_pad; -@@ -482,14 +482,14 @@ - { - Sym *sym; - -- next(); -- sym = label_find(tok); -+ next(s1); -+ sym = label_find(s1, tok); - if (!sym) { -- sym = label_push(&s1->asm_labels, tok, 0); -+ sym = label_push(s1, &s1->asm_labels, tok, 0); - sym->type.t = VT_VOID; - } - sym->type.t &= ~VT_STATIC; -- next(); -+ next(s1); - } - break; - case TOK_ASM_string: -@@ -500,19 +500,19 @@ - int i, size, t; - - t = tok; -- next(); -+ next(s1); - for(;;) { - if (tok != TOK_STR) -- expect("string constant"); -+ expect(s1, "string constant"); - p = tokc.cstr->data; - size = tokc.cstr->size; - if (t == TOK_ASM_ascii && size > 0) - size--; - for(i = 0; i < size; i++) -- g(p[i]); -- next(); -+ g(s1, p[i]); -+ next(s1); - if (tok == ',') { -- next(); -+ next(s1); - } else if (tok != TOK_STR) { - break; - } -@@ -526,12 +526,12 @@ - char sname[64]; - tok1 = tok; - n = 0; -- next(); -+ next(s1); - if (tok != ';' && tok != TOK_LINEFEED) { - n = asm_int_expr(s1); -- next(); -+ next(s1); - } -- sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); -+ sprintf(sname, (n?".%s%d":".%s"), get_tok_str(s1, tok1, NULL), n); - use_section(s1, sname); - } - break; -@@ -540,21 +540,21 @@ - char sname[256]; - - /* XXX: support more options */ -- next(); -+ next(s1); - sname[0] = '\0'; - while (tok != ';' && tok != TOK_LINEFEED && tok != ',') { - if (tok == TOK_STR) -- pstrcat(sname, sizeof(sname), tokc.cstr->data); -+ pstrcat(s1, sname, sizeof(sname), tokc.cstr->data); - else -- pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL)); -- next(); -+ pstrcat(s1, sname, sizeof(sname), get_tok_str(s1, tok, NULL)); -+ next(s1); - } - if (tok == ',') { - /* skip section options */ -- next(); -+ next(s1); - if (tok != TOK_STR) -- expect("string constant"); -- next(); -+ expect(s1, "string constant"); -+ next(s1); - } - last_text_section = cur_text_section; - use_section(s1, sname); -@@ -563,16 +563,16 @@ - case TOK_ASM_previous: - { - Section *sec; -- next(); -+ next(s1); - if (!last_text_section) -- error("no previous section referenced"); -+ tcc_error(s1, "no previous section referenced"); - sec = cur_text_section; - use_section1(s1, last_text_section); - last_text_section = sec; - } - break; - default: -- error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); -+ tcc_error(s1, "unknown assembler directive '.%s'", get_tok_str(s1, tok, NULL)); - break; - } - } -@@ -617,12 +617,12 @@ - - /* XXX: undefine C labels */ - -- ch = file->buf_ptr[0]; -- tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; -+ fch = file->buf_ptr[0]; -+ next_tok_flags = TOK_FLAG_BOW | TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_ASM_COMMENTS; - if (do_preprocess) - parse_flags |= PARSE_FLAG_PREPROCESS; -- next(); -+ next(s1); - for(;;) { - if (tok == TOK_EOF) - break; -@@ -631,7 +631,7 @@ - if (tok == '#') { - /* horrible gas comment */ - while (tok != TOK_LINEFEED) -- next(); -+ next(s1); - } else if (tok == '.') { - asm_parse_directive(s1); - } else if (tok == TOK_PPNUM) { -@@ -640,24 +640,24 @@ - p = tokc.cstr->data; - n = strtoul(p, (char **)&p, 10); - if (*p != '\0') -- expect("':'"); -+ expect(s1, "':'"); - /* new local label */ - asm_new_label(s1, asm_get_local_label_name(s1, n), 1); -- next(); -- skip(':'); -+ next(s1); -+ skip(s1, ':'); - goto redo; - } else if (tok >= TOK_IDENT) { - /* instruction or label */ - opcode = tok; -- next(); -+ next(s1); - if (tok == ':') { - /* new label */ - asm_new_label(s1, opcode, 0); -- next(); -+ next(s1); - goto redo; - } else if (tok == '=') { - int n; -- next(); -+ next(s1); - n = asm_int_expr(s1); - asm_new_label1(s1, opcode, 0, SHN_ABS, n); - goto redo; -@@ -667,10 +667,10 @@ - } - /* end of line */ - if (tok != ';' && tok != TOK_LINEFEED){ -- expect("end of line"); -+ expect(s1, "end of line"); - } - parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ -- next(); -+ next(s1); - } - - asm_free_labels(s1); -@@ -696,7 +696,7 @@ - - cur_text_section->data_offset = ind; - -- free_defines(define_start); -+ free_defines(s1, define_start); - - return ret; - } -@@ -712,15 +712,15 @@ - BufferedFile *bf, *saved_file; - int saved_parse_flags, *saved_macro_ptr; - -- bf = tcc_malloc(sizeof(BufferedFile)); -+ bf = tcc_malloc(s1, sizeof(BufferedFile)); - memset(bf, 0, sizeof(BufferedFile)); -- bf->fd = -1; -+ bf->fd = NULL; - bf->buf_ptr = str; - bf->buf_end = str + len; - str[len] = CH_EOB; - /* same name as current file so that errors are correctly - reported */ -- pstrcpy(bf->filename, sizeof(bf->filename), file->filename); -+ pstrcpy(s1, bf->filename, sizeof(bf->filename), file->filename); - bf->line_num = file->line_num; - saved_file = file; - file = bf; -@@ -733,22 +733,23 @@ - parse_flags = saved_parse_flags; - macro_ptr = saved_macro_ptr; - file = saved_file; -- tcc_free(bf); -+ ckfree((char *)bf); - } - - /* find a constraint by its number or id (gcc 3 extended - syntax). return -1 if not found. Return in *pp in char after the - constraint */ --static int find_constraint(ASMOperand *operands, int nb_operands, -+static int find_constraint(TCCState *s1, -+ ASMOperand *operands, int nb_operands, - const char *name, const char **pp) - { - int index; - TokenSym *ts; - const char *p; - -- if (isnum(*name)) { -+ if (isnum(s1, *name)) { - index = 0; -- while (isnum(*name)) { -+ while (isnum(s1, *name)) { - index = (index * 10) + (*name) - '0'; - name++; - } -@@ -758,7 +759,7 @@ - name++; - p = strchr(name, ']'); - if (p) { -- ts = tok_alloc(name, p - name); -+ ts = tok_alloc(s1, name, p - name); - for(index = 0; index < nb_operands; index++) { - if (operands[index].id == ts->tok) - goto found; -@@ -777,7 +778,8 @@ - return index; - } - --static void subst_asm_operands(ASMOperand *operands, int nb_operands, -+static void subst_asm_operands(TCCState *s1, -+ ASMOperand *operands, int nb_operands, - int nb_outputs, - CString *out_str, CString *in_str) - { -@@ -786,7 +788,7 @@ - ASMOperand *op; - SValue sv; - -- cstr_new(out_str); -+ cstr_new(s1, out_str); - str = in_str->data; - for(;;) { - c = *str++; -@@ -799,9 +801,9 @@ - if (*str == 'c' || *str == 'n' || - *str == 'b' || *str == 'w' || *str == 'h') - modifier = *str++; -- index = find_constraint(operands, nb_operands, str, &str); -+ index = find_constraint(s1, operands, nb_operands, str, &str); - if (index < 0) -- error("invalid operand reference after %%"); -+ tcc_error(s1, "invalid operand reference after %%"); - op = &operands[index]; - sv = *op->vt; - if (op->reg >= 0) { -@@ -809,10 +811,10 @@ - if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory) - sv.r |= VT_LVAL; - } -- subst_asm_operand(out_str, &sv, modifier); -+ subst_asm_operand(s1, out_str, &sv, modifier); - } else { - add_char: -- cstr_ccat(out_str, c); -+ cstr_ccat(s1, out_str, c); - if (c == '\0') - break; - } -@@ -820,7 +822,8 @@ - } - - --static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, -+static void parse_asm_operands(TCCState *s1, -+ ASMOperand *operands, int *nb_operands_ptr, - int is_output) - { - ASMOperand *op; -@@ -830,26 +833,26 @@ - nb_operands = *nb_operands_ptr; - for(;;) { - if (nb_operands >= MAX_ASM_OPERANDS) -- error("too many asm operands"); -+ tcc_error(s1, "too many asm operands"); - op = &operands[nb_operands++]; - op->id = 0; - if (tok == '[') { -- next(); -+ next(s1); - if (tok < TOK_IDENT) -- expect("identifier"); -+ expect(s1, "identifier"); - op->id = tok; -- next(); -- skip(']'); -+ next(s1); -+ skip(s1, ']'); - } - if (tok != TOK_STR) -- expect("string constant"); -- op->constraint = tcc_malloc(tokc.cstr->size); -+ expect(s1, "string constant"); -+ op->constraint = tcc_malloc(s1, tokc.cstr->size); - strcpy(op->constraint, tokc.cstr->data); -- next(); -- skip('('); -- gexpr(); -+ next(s1); -+ skip(s1, '('); -+ gexpr(s1); - if (is_output) { -- test_lvalue(); -+ test_lvalue(s1); - } else { - /* we want to avoid LLOCAL case, except when the 'm' - constraint is used. Note that it may come from -@@ -859,13 +862,13 @@ - ((vtop->r & VT_VALMASK) == VT_LLOCAL || - (vtop->r & VT_VALMASK) < VT_CONST) && - !strchr(op->constraint, 'm')) { -- gv(RC_INT); -+ gv(s1, RC_INT); - } - } - op->vt = vtop; -- skip(')'); -+ skip(s1, ')'); - if (tok == ',') { -- next(); -+ next(s1); - } else { - break; - } -@@ -874,62 +877,63 @@ - } - } - --static void parse_asm_str(CString *astr) -+static void parse_asm_str(TCCState *s1, -+ CString *astr) - { -- skip('('); -+ skip(s1, '('); - /* read the string */ - if (tok != TOK_STR) -- expect("string constant"); -- cstr_new(astr); -+ expect(s1, "string constant"); -+ cstr_new(s1, astr); - while (tok == TOK_STR) { - /* XXX: add \0 handling too ? */ -- cstr_cat(astr, tokc.cstr->data); -- next(); -+ cstr_cat(s1, astr, tokc.cstr->data); -+ next(s1); - } -- cstr_ccat(astr, '\0'); -+ cstr_ccat(s1, astr, '\0'); - } - - /* parse the GCC asm() instruction */ --static void asm_instr(void) -+static void asm_instr(TCCState *s1) - { - CString astr, astr1; - ASMOperand operands[MAX_ASM_OPERANDS]; - int nb_inputs, nb_outputs, nb_operands, i, must_subst, out_reg; - uint8_t clobber_regs[NB_ASM_REGS]; - -- next(); -+ next(s1); - /* since we always generate the asm() instruction, we can ignore - volatile */ - if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) { -- next(); -+ next(s1); - } -- parse_asm_str(&astr); -+ parse_asm_str(s1, &astr); - nb_operands = 0; - nb_outputs = 0; - must_subst = 0; - memset(clobber_regs, 0, sizeof(clobber_regs)); - if (tok == ':') { -- next(); -+ next(s1); - must_subst = 1; - /* output args */ -- parse_asm_operands(operands, &nb_operands, 1); -+ parse_asm_operands(s1, operands, &nb_operands, 1); - nb_outputs = nb_operands; - if (tok == ':') { -- next(); -+ next(s1); - if (tok != ')') { - /* input args */ -- parse_asm_operands(operands, &nb_operands, 0); -+ parse_asm_operands(s1, operands, &nb_operands, 0); - if (tok == ':') { - /* clobber list */ - /* XXX: handle registers */ -- next(); -+ next(s1); - for(;;) { - if (tok != TOK_STR) -- expect("string constant"); -- asm_clobber(clobber_regs, tokc.cstr->data); -- next(); -+ expect(s1, "string constant"); -+ asm_clobber(s1, clobber_regs, tokc.cstr->data); -+ next(s1); - if (tok == ',') { -- next(); -+ next(s1); - } else { - break; - } -@@ -938,18 +942,18 @@ - } - } - } -- skip(')'); -+ skip(s1, ')'); - /* NOTE: we do not eat the ';' so that we can restore the current - token after the assembler parsing */ - if (tok != ';') -- expect("';'"); -+ expect(s1, "';'"); - nb_inputs = nb_operands - nb_outputs; - - /* save all values in the memory */ -- save_regs(0); -+ save_regs(s1, 0); - - /* compute constraints */ -- asm_compute_constraints(operands, nb_operands, nb_outputs, -+ asm_compute_constraints(s1, operands, nb_operands, nb_outputs, - clobber_regs, &out_reg); - - /* substitute the operands in the asm string. No substitution is -@@ -958,8 +962,8 @@ - printf("asm: \"%s\"\n", (char *)astr.data); - #endif - if (must_subst) { -- subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr); -- cstr_free(&astr); -+ subst_asm_operands(s1, operands, nb_operands, nb_outputs, &astr1, &astr); -+ cstr_free(s1, &astr); - } else { - astr1 = astr; - } -@@ -968,40 +972,40 @@ - #endif - - /* generate loads */ -- asm_gen_code(operands, nb_operands, nb_outputs, 0, -+ asm_gen_code(s1, operands, nb_operands, nb_outputs, 0, - clobber_regs, out_reg); - - /* assemble the string with tcc internal assembler */ -- tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1); -+ tcc_assemble_inline(s1, astr1.data, astr1.size - 1); - - /* restore the current C token */ -- next(); -+ next(s1); - - /* store the output values if needed */ -- asm_gen_code(operands, nb_operands, nb_outputs, 1, -+ asm_gen_code(s1, operands, nb_operands, nb_outputs, 1, - clobber_regs, out_reg); - - /* free everything */ - for(i=0;iconstraint); -- vpop(); -+ ckfree(op->constraint); -+ vpop(s1 ); - } -- cstr_free(&astr1); -+ cstr_free(s1, &astr1); - } - --static void asm_global_instr(void) -+static void asm_global_instr(TCCState *s1) - { - CString astr; - -- next(); -- parse_asm_str(&astr); -- skip(')'); -+ next(s1); -+ parse_asm_str(s1, &astr); -+ skip(s1, ')'); - /* NOTE: we do not eat the ';' so that we can restore the current - token after the assembler parsing */ - if (tok != ';') -- expect("';'"); -+ expect(s1, "';'"); - - #ifdef ASM_DEBUG - printf("asm_global: \"%s\"\n", (char *)astr.data); -@@ -1010,12 +1014,12 @@ - ind = cur_text_section->data_offset; - - /* assemble the string with tcc internal assembler */ -- tcc_assemble_inline(tcc_state, astr.data, astr.size - 1); -+ tcc_assemble_inline(s1, astr.data, astr.size - 1); - - cur_text_section->data_offset = ind; - - /* restore the current C token */ -- next(); -+ next(s1); - -- cstr_free(&astr); -+ cstr_free(s1, &astr); - } ---- tcc-0.9.23/tcc.c 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/tcc.c 2007-11-07 10:04:32.000000000 -0500 -@@ -17,339 +17,73 @@ - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ --#define _GNU_SOURCE --#include "config.h" - --#ifdef CONFIG_TCCBOOT -+#include "tcc.h" - --#include "tccboot.h" --#define CONFIG_TCC_STATIC -+/* This stuff is used by the code generation backend. */ - --#else -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#ifdef WIN32 --#include --#endif --#ifndef WIN32 --#include --#include --#endif -- --#endif /* !CONFIG_TCCBOOT */ -- --#include "elf.h" --#include "stab.h" -- --#ifndef O_BINARY --#define O_BINARY 0 --#endif -- --#include "libtcc.h" -- --/* parser debug */ --//#define PARSE_DEBUG --/* preprocessor debug */ --//#define PP_DEBUG --/* include file debug */ --//#define INC_DEBUG -- --//#define MEM_DEBUG -- --/* assembler debug */ --//#define ASM_DEBUG -- --/* target selection */ --//#define TCC_TARGET_I386 /* i386 code generator */ --//#define TCC_TARGET_ARM /* ARMv4 code generator */ --//#define TCC_TARGET_C67 /* TMS320C67xx code generator */ -- --/* default target is I386 */ --#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ -- !defined(TCC_TARGET_C67) --#define TCC_TARGET_I386 --#endif -+static int ind; /* output code index */ -+static int loc; /* local variable index */ -+static Section *cur_text_section; /* current section where function code is generated */ -+static SValue *vtop; -+static Section *symtab_section; -+static CType func_vt; /* current function return type (used by return instruction) */ -+static int func_vc; -+static Section *lbounds_section; /* contains local data bound description */ -+/* Predefined types */ -+static CType char_pointer_type; -+static CType func_old_type; - --#if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \ -- !defined(TCC_TARGET_C67) --#define CONFIG_TCC_BCHECK /* enable bound checking code */ --#endif -+/* compile with built-in memory and bounds checker */ -+static int do_bounds_check = 0; - --#if defined(WIN32) && !defined(TCC_TARGET_PE) --#define CONFIG_TCC_STATIC -+#ifdef TCC_TARGET_I386 -+#include "i386/i386-gen.c" - #endif - --/* define it to include assembler support */ --#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) --#define CONFIG_TCC_ASM -+#ifdef TCC_TARGET_ARM -+#include "arm-gen.c" - #endif - --/* object format selection */ --#if defined(TCC_TARGET_C67) --#define TCC_TARGET_COFF -+#ifdef TCC_TARGET_C67 -+#include "c67-gen.c" - #endif - --#define FALSE 0 --#define false 0 --#define TRUE 1 --#define true 1 --typedef int BOOL; -- --/* path to find crt1.o, crti.o and crtn.o. Only needed when generating -- executables or dlls */ --#define CONFIG_TCC_CRT_PREFIX "/usr/lib" -- --#define INCLUDE_STACK_SIZE 32 --#define IFDEF_STACK_SIZE 64 --#define VSTACK_SIZE 256 --#define STRING_MAX_SIZE 1024 --#define PACK_STACK_SIZE 8 -- --#define TOK_HASH_SIZE 8192 /* must be a power of two */ --#define TOK_ALLOC_INCR 512 /* must be a power of two */ --#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ -- --/* token symbol management */ --typedef struct TokenSym { -- struct TokenSym *hash_next; -- struct Sym *sym_define; /* direct pointer to define */ -- struct Sym *sym_label; /* direct pointer to label */ -- struct Sym *sym_struct; /* direct pointer to structure */ -- struct Sym *sym_identifier; /* direct pointer to identifier */ -- int tok; /* token number */ -- int len; -- char str[1]; --} TokenSym; -- --typedef struct CString { -- int size; /* size in bytes */ -- void *data; /* either 'char *' or 'int *' */ -- int size_allocated; -- void *data_allocated; /* if non NULL, data has been malloced */ --} CString; -- --/* type definition */ --typedef struct CType { -- int t; -- struct Sym *ref; --} CType; -- --/* constant value */ --typedef union CValue { -- long double ld; -- double d; -- float f; -- int i; -- unsigned int ui; -- unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */ -- long long ll; -- unsigned long long ull; -- struct CString *cstr; -- void *ptr; -- int tab[1]; --} CValue; -- --/* value on stack */ --typedef struct SValue { -- CType type; /* type */ -- unsigned short r; /* register + flags */ -- unsigned short r2; /* second register, used for 'long long' -- type. If not used, set to VT_CONST */ -- CValue c; /* constant, if VT_CONST */ -- struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */ --} SValue; -- --/* symbol management */ --typedef struct Sym { -- int v; /* symbol token */ -- int r; /* associated register */ -- int c; /* associated number */ -- CType type; /* associated type */ -- struct Sym *next; /* next related symbol */ -- struct Sym *prev; /* prev symbol in stack */ -- struct Sym *prev_tok; /* previous symbol for this token */ --} Sym; -- --/* 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 -- --typedef struct Section { -- unsigned long data_offset; /* current data offset */ -- unsigned char *data; /* section data */ -- unsigned long data_allocated; /* used for realloc() handling */ -- int sh_name; /* elf section name (only used during output) */ -- int sh_num; /* elf section number */ -- int sh_type; /* elf section type */ -- int sh_flags; /* elf section flags */ -- int sh_info; /* elf section info */ -- int sh_addralign; /* elf section alignment */ -- int sh_entsize; /* elf entry size */ -- unsigned long sh_size; /* section size (only used during output) */ -- unsigned long sh_addr; /* address at which the section is relocated */ -- unsigned long sh_offset; /* address at which the section is relocated */ -- int nb_hashed_syms; /* used to resize the hash table */ -- struct Section *link; /* link to another section */ -- struct Section *reloc; /* corresponding section for relocation, if any */ -- struct Section *hash; /* hash table for symbols */ -- struct Section *next; -- char name[1]; /* section name */ --} Section; -- --typedef struct DLLReference { -- int level; -- char name[1]; --} DLLReference; -- --/* GNUC attribute definition */ --typedef struct AttributeDef { -- int aligned; -- int packed; -- Section *section; -- unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */ -- unsigned char dllexport; --} AttributeDef; -- --#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */ --#define SYM_FIELD 0x20000000 /* struct/union field symbol space */ --#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */ -- --/* stored in 'Sym.c' field */ --#define FUNC_NEW 1 /* ansi function prototype */ --#define FUNC_OLD 2 /* old function prototype */ --#define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */ -- --/* stored in 'Sym.r' field */ --#define FUNC_CDECL 0 /* standard c call */ --#define FUNC_STDCALL 1 /* pascal c call */ --#define FUNC_FASTCALL1 2 /* first param in %eax */ --#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */ --#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */ -- --/* field 'Sym.t' for macros */ --#define MACRO_OBJ 0 /* object like macro */ --#define MACRO_FUNC 1 /* function like macro */ -- --/* field 'Sym.r' for C labels */ --#define LABEL_DEFINED 0 /* label is defined */ --#define LABEL_FORWARD 1 /* label is forward defined */ --#define LABEL_DECLARED 2 /* label is declared but never used */ -- --/* type_decl() types */ --#define TYPE_ABSTRACT 1 /* type without variable */ --#define TYPE_DIRECT 2 /* type with variable */ -- --#define IO_BUF_SIZE 8192 -- --typedef struct BufferedFile { -- uint8_t *buf_ptr; -- uint8_t *buf_end; -- int fd; -- int line_num; /* current line number - here to simplify code */ -- int ifndef_macro; /* #ifndef macro / #endif search */ -- int ifndef_macro_saved; /* saved ifndef_macro */ -- int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */ -- char inc_type; /* type of include */ -- char inc_filename[512]; /* filename specified by the user */ -- char filename[1024]; /* current filename - here to simplify code */ -- unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */ --} BufferedFile; -- --#define CH_EOB '\\' /* end of buffer or '\0' char in file */ --#define CH_EOF (-1) /* end of file */ -- --/* parsing state (used to save parser state to reparse part of the -- source several times) */ --typedef struct ParseState { -- int *macro_ptr; -- int line_num; -- int tok; -- CValue tokc; --} ParseState; -- --/* used to record tokens */ --typedef struct TokenString { -- int *str; -- int len; -- int allocated_len; -- int last_line_num; --} TokenString; -- --/* include file cache, used to find files faster and also to eliminate -- inclusion if the include file is protected by #ifndef ... #endif */ --typedef struct CachedInclude { -- int ifndef_macro; -- int hash_next; /* -1 if none */ -- char type; /* '"' or '>' to give include type */ -- char filename[1]; /* path specified in #include */ --} CachedInclude; -- --#define CACHED_INCLUDES_HASH_SIZE 512 -- - /* parser */ - static struct BufferedFile *file; --static int ch, tok; -+static int fch, tok; - static CValue tokc; - static CString tokcstr; /* current parsed string, if any */ - /* additional informations about token */ --static int tok_flags; --#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ --#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ --#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ -+static int tok_flags, next_tok_flags; - - static int *macro_ptr, *macro_ptr_allocated; - static int *unget_saved_macro_ptr; - static int unget_saved_buffer[TOK_MAX_SIZE + 1]; - static int unget_buffer_enabled; - static int parse_flags; --#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ --#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ --#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a -- token. line feed is also -- returned at eof */ --#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */ -- - static Section *text_section, *data_section, *bss_section; /* predefined sections */ --static Section *cur_text_section; /* current section where function code is -- generated */ - #ifdef CONFIG_TCC_ASM - static Section *last_text_section; /* to handle .previous asm directive */ - #endif -+ - /* bound check related sections */ - static Section *bounds_section; /* contains global data bound description */ --static Section *lbounds_section; /* contains local data bound description */ - /* symbol sections */ --static Section *symtab_section, *strtab_section; -+static Section *strtab_section; - - /* debug sections */ - static Section *stab_section, *stabstr_section; - --/* loc : local variable index -- ind : output code index -+/* - rsym: return symbol - anon_sym: anonymous symbol index - */ --static int rsym, anon_sym, ind, loc; -+static int rsym, anon_sym; - /* expression generation modifiers */ - static int const_wanted; /* true if constant wanted */ --static int nocode_wanted; /* true if no code generation wanted for an expression */ - static int global_expr; /* true if compound literals must be allocated - globally (used during initializers parsing */ --static CType func_vt; /* current function return type (used by return -- instruction) */ --static int func_vc; - static int last_line_num, last_ind, func_ind; /* debug last line number and pc */ - static int tok_ident; - static TokenSym **table_ident; -@@ -360,21 +94,17 @@ - static Sym *define_stack; - static Sym *global_label_stack, *local_label_stack; - /* symbol allocator */ --#define SYM_POOL_NB (8192 / sizeof(Sym)) - static Sym *sym_free_first; - --static SValue vstack[VSTACK_SIZE], *vtop; -+static SValue vstack[VSTACK_SIZE]; - /* some predefined types */ --static CType char_pointer_type, func_old_type, int_type; --/* true if isid(c) || isnum(c) */ -+static CType int_type; -+/* true if isid(c) || isnum(st, c) */ - static unsigned char isidnum_table[256]; - - /* compile with debug symbol (and use them if error during execution) */ - static int do_debug = 0; - --/* compile with built-in memory and bounds checker */ --static int do_bounds_check = 0; -- - /* display benchmark infos */ - #if !defined(LIBTCC) - static int do_bench = 0; -@@ -392,581 +122,19 @@ - static int num_callers = 6; - static const char **rt_bound_error_msg; - --/* XXX: get rid of this ASAP */ --static struct TCCState *tcc_state; -- --/* give the path of the tcc libraries */ --static const char *tcc_lib_path = CONFIG_TCCDIR; -- --struct TCCState { -- int output_type; -- -- BufferedFile **include_stack_ptr; -- int *ifdef_stack_ptr; -- -- /* include file handling */ -- char **include_paths; -- int nb_include_paths; -- char **sysinclude_paths; -- int nb_sysinclude_paths; -- CachedInclude **cached_includes; -- int nb_cached_includes; -- -- char **library_paths; -- int nb_library_paths; -- -- /* array of all loaded dlls (including those referenced by loaded -- dlls) */ -- DLLReference **loaded_dlls; -- int nb_loaded_dlls; -- -- /* sections */ -- Section **sections; -- int nb_sections; /* number of sections, including first dummy section */ -- -- /* got handling */ -- Section *got; -- Section *plt; -- unsigned long *got_offsets; -- int nb_got_offsets; -- /* give the correspondance from symtab indexes to dynsym indexes */ -- int *symtab_to_dynsym; -- -- /* temporary dynamic symbol sections (for dll loading) */ -- Section *dynsymtab_section; -- /* exported dynamic symbol section */ -- Section *dynsym; -- -- int nostdinc; /* if true, no standard headers are added */ -- int nostdlib; /* if true, no standard libraries are added */ -- -- int nocommon; /* if true, do not use common symbols for .bss data */ -- -- /* if true, static linking is performed */ -- int static_link; -- -- /* if true, all symbols are exported */ -- int rdynamic; -- -- /* if true, only link in referenced objects from archive */ -- int alacarte_link; -- -- /* address of text section */ -- unsigned long text_addr; -- int has_text_addr; -- -- /* output format, see TCC_OUTPUT_FORMAT_xxx */ -- int output_format; -- -- /* C language options */ -- int char_is_unsigned; -- int leading_underscore; -- -- /* warning switches */ -- int warn_write_strings; -- int warn_unsupported; -- int warn_error; -- int warn_none; -- int warn_implicit_function_declaration; -- -- /* error handling */ -- void *error_opaque; -- void (*error_func)(void *opaque, const char *msg); -- int error_set_jmp_enabled; -- jmp_buf error_jmp_buf; -- int nb_errors; -- -- /* tiny assembler state */ -- Sym *asm_labels; -- -- /* see include_stack_ptr */ -- BufferedFile *include_stack[INCLUDE_STACK_SIZE]; -- -- /* see ifdef_stack_ptr */ -- int ifdef_stack[IFDEF_STACK_SIZE]; -- -- /* see cached_includes */ -- int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE]; -- -- /* pack stack */ -- int pack_stack[PACK_STACK_SIZE]; -- int *pack_stack_ptr; --}; -- --/* The current value can be: */ --#define VT_VALMASK 0x00ff --#define VT_CONST 0x00f0 /* constant in vc -- (must be first non register value) */ --#define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */ --#define VT_LOCAL 0x00f2 /* offset on stack */ --#define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */ --#define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */ --#define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */ --#define VT_LVAL 0x0100 /* var is an lvalue */ --#define VT_SYM 0x0200 /* a symbol value is added */ --#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for -- char/short stored in integer registers) */ --#define VT_MUSTBOUND 0x0800 /* bound checking must be done before -- dereferencing value */ --#define VT_BOUNDED 0x8000 /* value is bounded. The address of the -- bounding function call point is in vc */ --#define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */ --#define VT_LVAL_SHORT 0x2000 /* lvalue is a short */ --#define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */ --#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED) -- --/* types */ --#define VT_INT 0 /* integer type */ --#define VT_BYTE 1 /* signed byte type */ --#define VT_SHORT 2 /* short type */ --#define VT_VOID 3 /* void type */ --#define VT_PTR 4 /* pointer */ --#define VT_ENUM 5 /* enum definition */ --#define VT_FUNC 6 /* function type */ --#define VT_STRUCT 7 /* struct/union definition */ --#define VT_FLOAT 8 /* IEEE float */ --#define VT_DOUBLE 9 /* IEEE double */ --#define VT_LDOUBLE 10 /* IEEE long double */ --#define VT_BOOL 11 /* ISOC99 boolean type */ --#define VT_LLONG 12 /* 64 bit integer */ --#define VT_LONG 13 /* long integer (NEVER USED as type, only -- during parsing) */ --#define VT_BTYPE 0x000f /* mask for basic type */ --#define VT_UNSIGNED 0x0010 /* unsigned type */ --#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */ --#define VT_BITFIELD 0x0040 /* bitfield modifier */ --#define VT_CONSTANT 0x0800 /* const modifier */ --#define VT_VOLATILE 0x1000 /* volatile modifier */ --#define VT_SIGNED 0x2000 /* signed type */ -- --/* storage */ --#define VT_EXTERN 0x00000080 /* extern definition */ --#define VT_STATIC 0x00000100 /* static variable */ --#define VT_TYPEDEF 0x00000200 /* typedef definition */ --#define VT_INLINE 0x00000400 /* inline definition */ -- --#define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ -- --/* type mask (except storage) */ --#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) --#define VT_TYPE (~(VT_STORAGE)) -- --/* token values */ -- --/* warning: the following compare tokens depend on i386 asm code */ --#define TOK_ULT 0x92 --#define TOK_UGE 0x93 --#define TOK_EQ 0x94 --#define TOK_NE 0x95 --#define TOK_ULE 0x96 --#define TOK_UGT 0x97 --#define TOK_LT 0x9c --#define TOK_GE 0x9d --#define TOK_LE 0x9e --#define TOK_GT 0x9f -- --#define TOK_LAND 0xa0 --#define TOK_LOR 0xa1 -- --#define TOK_DEC 0xa2 --#define TOK_MID 0xa3 /* inc/dec, to void constant */ --#define TOK_INC 0xa4 --#define TOK_UDIV 0xb0 /* unsigned division */ --#define TOK_UMOD 0xb1 /* unsigned modulo */ --#define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */ --#define TOK_CINT 0xb3 /* number in tokc */ --#define TOK_CCHAR 0xb4 /* char constant in tokc */ --#define TOK_STR 0xb5 /* pointer to string in tokc */ --#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */ --#define TOK_LCHAR 0xb7 --#define TOK_LSTR 0xb8 --#define TOK_CFLOAT 0xb9 /* float constant */ --#define TOK_LINENUM 0xba /* line number info */ --#define TOK_CDOUBLE 0xc0 /* double constant */ --#define TOK_CLDOUBLE 0xc1 /* long double constant */ --#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */ --#define TOK_ADDC1 0xc3 /* add with carry generation */ --#define TOK_ADDC2 0xc4 /* add with carry use */ --#define TOK_SUBC1 0xc5 /* add with carry generation */ --#define TOK_SUBC2 0xc6 /* add with carry use */ --#define TOK_CUINT 0xc8 /* unsigned int constant */ --#define TOK_CLLONG 0xc9 /* long long constant */ --#define TOK_CULLONG 0xca /* unsigned long long constant */ --#define TOK_ARROW 0xcb --#define TOK_DOTS 0xcc /* three dots */ --#define TOK_SHR 0xcd /* unsigned shift right */ --#define TOK_PPNUM 0xce /* preprocessor number */ -- --#define TOK_SHL 0x01 /* shift left */ --#define TOK_SAR 0x02 /* signed shift right */ -- --/* assignement operators : normal operator or 0x80 */ --#define TOK_A_MOD 0xa5 --#define TOK_A_AND 0xa6 --#define TOK_A_MUL 0xaa --#define TOK_A_ADD 0xab --#define TOK_A_SUB 0xad --#define TOK_A_DIV 0xaf --#define TOK_A_XOR 0xde --#define TOK_A_OR 0xfc --#define TOK_A_SHL 0x81 --#define TOK_A_SAR 0x82 -- --#ifndef offsetof --#define offsetof(type, field) ((size_t) &((type *)0)->field) --#endif -- --#ifndef countof --#define countof(tab) (sizeof(tab) / sizeof((tab)[0])) --#endif -- --/* WARNING: the content of this string encodes token numbers */ --static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266"; -- --#define TOK_EOF (-1) /* end of file */ --#define TOK_LINEFEED 10 /* line feed */ -- --/* all identificators and strings have token above that */ --#define TOK_IDENT 256 -- --/* only used for i386 asm opcodes definitions */ --#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x) -- --#define DEF_BWL(x) \ -- DEF(TOK_ASM_ ## x ## b, #x "b") \ -- DEF(TOK_ASM_ ## x ## w, #x "w") \ -- DEF(TOK_ASM_ ## x ## l, #x "l") \ -- DEF(TOK_ASM_ ## x, #x) -- --#define DEF_WL(x) \ -- DEF(TOK_ASM_ ## x ## w, #x "w") \ -- DEF(TOK_ASM_ ## x ## l, #x "l") \ -- DEF(TOK_ASM_ ## x, #x) -- --#define DEF_FP1(x) \ -- DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \ -- DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \ -- DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \ -- DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s") -- --#define DEF_FP(x) \ -- DEF(TOK_ASM_ ## f ## x, "f" #x ) \ -- DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \ -- DEF_FP1(x) -- --#define DEF_ASMTEST(x) \ -- DEF_ASM(x ## o) \ -- DEF_ASM(x ## no) \ -- DEF_ASM(x ## b) \ -- DEF_ASM(x ## c) \ -- DEF_ASM(x ## nae) \ -- DEF_ASM(x ## nb) \ -- DEF_ASM(x ## nc) \ -- DEF_ASM(x ## ae) \ -- DEF_ASM(x ## e) \ -- DEF_ASM(x ## z) \ -- DEF_ASM(x ## ne) \ -- DEF_ASM(x ## nz) \ -- DEF_ASM(x ## be) \ -- DEF_ASM(x ## na) \ -- DEF_ASM(x ## nbe) \ -- DEF_ASM(x ## a) \ -- DEF_ASM(x ## s) \ -- DEF_ASM(x ## ns) \ -- DEF_ASM(x ## p) \ -- DEF_ASM(x ## pe) \ -- DEF_ASM(x ## np) \ -- DEF_ASM(x ## po) \ -- DEF_ASM(x ## l) \ -- DEF_ASM(x ## nge) \ -- DEF_ASM(x ## nl) \ -- DEF_ASM(x ## ge) \ -- DEF_ASM(x ## le) \ -- DEF_ASM(x ## ng) \ -- DEF_ASM(x ## nle) \ -- DEF_ASM(x ## g) -- --#define TOK_ASM_int TOK_INT -- --enum tcc_token { -- TOK_LAST = TOK_IDENT - 1, --#define DEF(id, str) id, --#include "tcctok.h" --#undef DEF --}; -- --static const char tcc_keywords[] = --#define DEF(id, str) str "\0" --#include "tcctok.h" --#undef DEF --; -- --#define TOK_UIDENT TOK_DEFINE -- --#ifdef WIN32 --int __stdcall GetModuleFileNameA(void *, char *, int); --void *__stdcall GetProcAddress(void *, const char *); --void *__stdcall GetModuleHandleA(const char *); --void *__stdcall LoadLibraryA(const char *); --int __stdcall FreeConsole(void); -- --#define snprintf _snprintf --#define vsnprintf _vsnprintf --#ifndef __GNUC__ -- #define strtold (long double)strtod -- #define strtof (float)strtod -- #define strtoll (long long)strtol --#endif --#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) --/* currently incorrect */ --long double strtold(const char *nptr, char **endptr) --{ -- return (long double)strtod(nptr, endptr); --} --float strtof(const char *nptr, char **endptr) --{ -- return (float)strtod(nptr, endptr); --} --#else --/* XXX: need to define this to use them in non ISOC99 context */ --extern float strtof (const char *__nptr, char **__endptr); --extern long double strtold (const char *__nptr, char **__endptr); --#endif -- --static char *pstrcpy(char *buf, int buf_size, const char *s); --static char *pstrcat(char *buf, int buf_size, const char *s); --static const char *tcc_basename(const char *name); -- --static void next(void); --static void next_nomacro(void); --static void parse_expr_type(CType *type); --static void expr_type(CType *type); --static void unary_type(CType *type); --static void block(int *bsym, int *csym, int *case_sym, int *def_sym, -- int case_reg, int is_expr); --static int expr_const(void); --static void expr_eq(void); --static void gexpr(void); --static void gen_inline_functions(void); --static void decl(int l); --static void decl_initializer(CType *type, Section *sec, unsigned long c, -- int first, int size_only); --static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, -- int has_init, int v, int scope); --int gv(int rc); --void gv2(int rc1, int rc2); --void move_reg(int r, int s); --void save_regs(int n); --void save_reg(int r); --void vpop(void); --void vswap(void); --void vdup(void); --int get_reg(int rc); --int get_reg_ex(int rc,int rc2); -- --struct macro_level { -- struct macro_level *prev; -- int *p; --}; -- --static void macro_subst(TokenString *tok_str, Sym **nested_list, -- const int *macro_str, struct macro_level **can_read_stream); --void gen_op(int op); --void force_charshort_cast(int t); --static void gen_cast(CType *type); --void vstore(void); --static Sym *sym_find(int v); --static Sym *sym_push(int v, CType *type, int r, int c); -- --/* type handling */ --static int type_size(CType *type, int *a); --static inline CType *pointed_type(CType *type); --static int pointed_size(CType *type); --static int lvalue_type(int t); --static int parse_btype(CType *type, AttributeDef *ad); --static void type_decl(CType *type, AttributeDef *ad, int *v, int td); --static int is_compatible_types(CType *type1, CType *type2); -- --int ieee_finite(double d); --void error(const char *fmt, ...); --void vpushi(int v); --void vrott(int n); --void vnrott(int n); --void lexpand_nr(void); --static void vpush_global_sym(CType *type, int v); --void vset(CType *type, int r, int v); --void type_to_str(char *buf, int buf_size, -- CType *type, const char *varstr); --char *get_tok_str(int v, CValue *cv); --static Sym *get_sym_ref(CType *type, Section *sec, -- unsigned long offset, unsigned long size); --static Sym *external_global_sym(int v, CType *type, int r); -- --/* section generation */ --static void section_realloc(Section *sec, unsigned long new_size); --static void *section_ptr_add(Section *sec, unsigned long size); --static void put_extern_sym(Sym *sym, Section *section, -- unsigned long value, unsigned long size); --static void greloc(Section *s, Sym *sym, unsigned long addr, int type); --static int put_elf_str(Section *s, const char *sym); --static int put_elf_sym(Section *s, -- unsigned long value, unsigned long size, -- int info, int other, int shndx, const char *name); --static int add_elf_sym(Section *s, unsigned long value, unsigned long size, -- int info, int other, int sh_num, const char *name); --static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, -- int type, int symbol); --static void put_stabs(const char *str, int type, int other, int desc, -- unsigned long value); --static void put_stabs_r(const char *str, int type, int other, int desc, -- unsigned long value, Section *sec, int sym_index); --static void put_stabn(int type, int other, int desc, int value); --static void put_stabd(int type, int other, int desc); --static int tcc_add_dll(TCCState *s, const char *filename, int flags); -- --#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */ --#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ --static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); -- --/* tcccoff.c */ --int tcc_output_coff(TCCState *s1, FILE *f); -- --/* tccpe.c */ --void *resolve_sym(TCCState *s1, const char *sym, int type); --int pe_load_def_file(struct TCCState *s1, FILE *fp); --void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file); --unsigned long pe_add_runtime(struct TCCState *s1); --int tcc_output_pe(struct TCCState *s1, const char *filename); -- --/* tccasm.c */ -- --#ifdef CONFIG_TCC_ASM -- --typedef struct ExprValue { -- uint32_t v; -- Sym *sym; --} ExprValue; -- --#define MAX_ASM_OPERANDS 30 -- --typedef struct ASMOperand { -- int id; /* GCC 3 optionnal identifier (0 if number only supported */ -- char *constraint; -- char asm_str[16]; /* computed asm string for operand */ -- SValue *vt; /* C value of the expression */ -- int ref_index; /* if >= 0, gives reference to a output constraint */ -- int input_index; /* if >= 0, gives reference to an input constraint */ -- int priority; /* priority, used to assign registers */ -- int reg; /* if >= 0, register number used for this operand */ -- int is_llong; /* true if double register value */ -- int is_memory; /* true if memory operand */ -- int is_rw; /* for '+' modifier */ --} ASMOperand; -- --static void asm_expr(TCCState *s1, ExprValue *pe); --static int asm_int_expr(TCCState *s1); --static int find_constraint(ASMOperand *operands, int nb_operands, -- const char *name, const char **pp); -- --static int tcc_assemble(TCCState *s1, int do_preprocess); -- --#endif -- --static void asm_instr(void); --static void asm_global_instr(void); -- --/* true if float/double/long double type */ --static inline int is_float(int t) --{ -- int bt; -- bt = t & VT_BTYPE; -- return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; --} -- --#ifdef TCC_TARGET_I386 --#include "i386-gen.c" --#endif -- --#ifdef TCC_TARGET_ARM --#include "arm-gen.c" --#endif -- --#ifdef TCC_TARGET_C67 --#include "c67-gen.c" --#endif -- --#ifdef CONFIG_TCC_STATIC -- --#define RTLD_LAZY 0x001 --#define RTLD_NOW 0x002 --#define RTLD_GLOBAL 0x100 --#define RTLD_DEFAULT NULL -- --/* dummy function for profiling */ --void *dlopen(const char *filename, int flag) --{ -- return NULL; --} -- --const char *dlerror(void) --{ -- return "error"; --} -- --typedef struct TCCSyms { -- char *str; -- void *ptr; --} TCCSyms; -- --#define TCCSYM(a) { #a, &a, }, -- --/* add the symbol you want here if no dynamic linking is done */ --static TCCSyms tcc_syms[] = { --#if !defined(CONFIG_TCCBOOT) -- TCCSYM(printf) -- TCCSYM(fprintf) -- TCCSYM(fopen) -- TCCSYM(fclose) --#endif -- { NULL, NULL }, --}; -- --void *resolve_sym(TCCState *s1, const char *symbol, int type) --{ -- TCCSyms *p; -- p = tcc_syms; -- while (p->str != NULL) { -- if (!strcmp(p->str, symbol)) -- return p->ptr; -- p++; -- } -- return NULL; --} -- --#elif !defined(WIN32) -- --#include -- --void *resolve_sym(TCCState *s1, const char *sym, int type) --{ -- return dlsym(RTLD_DEFAULT, sym); --} -- --#endif -- - /********************************************************/ - - /* we use our own 'finite' function to avoid potential problems with - non standard math libs */ - /* XXX: endianness dependent */ --int ieee_finite(double d) -+int ieee_finite(TCCState *st, double d) - { - int *p = (int *)&d; - return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; - } - - /* copy a string and truncate it. */ --static char *pstrcpy(char *buf, int buf_size, const char *s) -+static char *pstrcpy(TCCState *st, char *buf, int buf_size, const char *s) - { - char *q, *q_end; - int c; -@@ -976,9 +144,8 @@ - q_end = buf + buf_size - 1; - while (q < q_end) { - c = *s++; -- if (c == '\0') -- break; - *q++ = c; -+ if (!c) break; - } - *q = '\0'; - } -@@ -986,16 +153,16 @@ - } - - /* strcat and truncate. */ --static char *pstrcat(char *buf, int buf_size, const char *s) -+static char *pstrcat(TCCState *st, char *buf, int buf_size, const char *s) - { - int len; - len = strlen(buf); - if (len < buf_size) -- pstrcpy(buf + len, buf_size - len, s); -+ pstrcpy(st, buf + len, buf_size - len, s); - return buf; - } - --static int strstart(const char *str, const char *val, const char **ptr) -+static int strstart(TCCState *st, const char *str, const char *val, const char **ptr) - { - const char *p, *q; - p = str; -@@ -1011,71 +178,39 @@ - return 1; - } - --/* memory management */ --#ifdef MEM_DEBUG --int mem_cur_size; --int mem_max_size; --#endif -- --static inline void tcc_free(void *ptr) --{ --#ifdef MEM_DEBUG -- mem_cur_size -= malloc_usable_size(ptr); --#endif -- free(ptr); --} -- --static void *tcc_malloc(unsigned long size) -+static void *tcc_malloc(TCCState *st, unsigned long size) - { -- void *ptr; -- ptr = malloc(size); -- if (!ptr && size) -- error("memory full"); --#ifdef MEM_DEBUG -- mem_cur_size += malloc_usable_size(ptr); -- if (mem_cur_size > mem_max_size) -- mem_max_size = mem_cur_size; --#endif -+ void *ptr = attemptckalloc(size); -+ if (!ptr && size)tcc_error(st, "memory full"); - return ptr; - } - --static void *tcc_mallocz(unsigned long size) -+static void *tcc_mallocz(TCCState *st, unsigned long size) - { - void *ptr; -- ptr = tcc_malloc(size); -+ ptr = tcc_malloc(st, size); - memset(ptr, 0, size); - return ptr; - } - --static inline void *tcc_realloc(void *ptr, unsigned long size) -+static inline void *tcc_realloc(TCCState *st, void *ptr, unsigned long size) - { -- void *ptr1; --#ifdef MEM_DEBUG -- mem_cur_size -= malloc_usable_size(ptr); --#endif -- ptr1 = realloc(ptr, size); --#ifdef MEM_DEBUG -- /* NOTE: count not correct if alloc error, but not critical */ -- mem_cur_size += malloc_usable_size(ptr1); -- if (mem_cur_size > mem_max_size) -- mem_max_size = mem_cur_size; --#endif -+ void *ptr1 = attemptckrealloc(ptr, size); -+ if (!ptr1 && size)tcc_error(st, "memory full"); - return ptr1; - } - --static char *tcc_strdup(const char *str) -+static char *tcc_strdup(TCCState *st, const char *str) - { - char *ptr; -- ptr = tcc_malloc(strlen(str) + 1); -+ ptr = tcc_malloc(st, strlen(str) + 1); - strcpy(ptr, str); - return ptr; - } - --#define free(p) use_tcc_free(p) --#define malloc(s) use_tcc_malloc(s) --#define realloc(p, s) use_tcc_realloc(p, s) -+#define malloc(s) ckalloc(s) - --static void dynarray_add(void ***ptab, int *nb_ptr, void *data) -+static void dynarray_add(TCCState *st, void ***ptab, int *nb_ptr, void *data) - { - int nb, nb_alloc; - void **pp; -@@ -1088,9 +223,9 @@ - nb_alloc = 1; - else - nb_alloc = nb * 2; -- pp = tcc_realloc(pp, nb_alloc * sizeof(void *)); -+ pp = tcc_realloc(st, pp, nb_alloc * sizeof(void *)); - if (!pp) -- error("memory full"); -+ tcc_error(st, "memory full"); - *ptab = pp; - } - pp[nb++] = data; -@@ -1098,12 +233,12 @@ - } - - /* symbol allocator */ --static Sym *__sym_malloc(void) -+static Sym *__sym_malloc(TCCState *st) - { - Sym *sym_pool, *sym, *last_sym; - int i; - -- sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym)); -+ sym_pool = tcc_malloc(st, SYM_POOL_NB * sizeof(Sym)); - - last_sym = sym_free_first; - sym = sym_pool; -@@ -1116,27 +251,27 @@ - return last_sym; - } - --static inline Sym *sym_malloc(void) -+static inline Sym *sym_malloc(TCCState * st) - { - Sym *sym; - sym = sym_free_first; - if (!sym) -- sym = __sym_malloc(); -+ sym = __sym_malloc(st); - sym_free_first = sym->next; - return sym; - } - --static inline void sym_free(Sym *sym) -+static inline void sym_free(TCCState *st, Sym *sym) - { - sym->next = sym_free_first; - sym_free_first = sym; - } - --Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) -+Section *new_section(TCCState *st, const char *name, int sh_type, int sh_flags) - { - Section *sec; - -- sec = tcc_mallocz(sizeof(Section) + strlen(name)); -+ sec = tcc_mallocz(st,sizeof(Section) + strlen(name)); - strcpy(sec->name, name); - sec->sh_type = sh_type; - sec->sh_flags = sh_flags; -@@ -1158,20 +293,20 @@ - - /* only add section if not private */ - if (!(sh_flags & SHF_PRIVATE)) { -- sec->sh_num = s1->nb_sections; -- dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); -+ sec->sh_num = st->nb_sections; -+ dynarray_add(st, (void ***)&st->sections, &st->nb_sections, sec); - } - return sec; - } - --static void free_section(Section *s) -+static void free_section(TCCState *st, Section *s) - { -- tcc_free(s->data); -- tcc_free(s); -+ ckfree((char *)(s->data)); -+ ckfree((char *)s); - } - - /* realloc section and set its content to zero */ --static void section_realloc(Section *sec, unsigned long new_size) -+static void section_realloc(TCCState * st, Section *sec, unsigned long new_size) - { - unsigned long size; - unsigned char *data; -@@ -1181,9 +316,9 @@ - size = 1; - while (size < new_size) - size = size * 2; -- data = tcc_realloc(sec->data, size); -+ data = tcc_realloc(st, sec->data, size); - if (!data) -- error("memory full"); -+ tcc_error(st, "memory full"); - memset(data + sec->data_allocated, 0, size - sec->data_allocated); - sec->data = data; - sec->data_allocated = size; -@@ -1191,38 +326,38 @@ - - /* reserve at least 'size' bytes in section 'sec' from - sec->data_offset. */ --static void *section_ptr_add(Section *sec, unsigned long size) -+static void *section_ptr_add(TCCState *st, Section *sec, unsigned long size) - { - unsigned long offset, offset1; - - offset = sec->data_offset; - offset1 = offset + size; - if (offset1 > sec->data_allocated) -- section_realloc(sec, offset1); -+ section_realloc(st, sec, offset1); - sec->data_offset = offset1; - return sec->data + offset; - } - - /* return a reference to a section, and create it if it does not - exists */ --Section *find_section(TCCState *s1, const char *name) -+Section *find_section(TCCState *st, const char *name) - { - Section *sec; - int i; -- for(i = 1; i < s1->nb_sections; i++) { -- sec = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ sec = st->sections[i]; - if (!strcmp(name, sec->name)) - return sec; - } - /* sections are created as PROGBITS */ -- return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); -+ return new_section(st, name, SHT_PROGBITS, SHF_ALLOC); - } - - #define SECTION_ABS ((void *)1) - - /* update sym->c so that it points to an external symbol in section - 'section' with value 'value' */ --static void put_extern_sym2(Sym *sym, Section *section, -+static void put_extern_sym2(TCCState * st, Sym *sym, Section *section, - unsigned long value, unsigned long size, - int can_add_underscore) - { -@@ -1247,8 +382,8 @@ - else - sym_bind = STB_GLOBAL; - -- name = get_tok_str(sym->v, NULL); --#ifdef CONFIG_TCC_BCHECK -+ name = get_tok_str(st, sym->v, NULL); -+#if 0 - if (do_bounds_check) { - char buf[32]; - -@@ -1269,6 +404,7 @@ - case TOK_memset: - case TOK_strlen: - case TOK_strcpy: -+ case TOK_alloca: - strcpy(buf, "__bound_"); - strcat(buf, name); - name = buf; -@@ -1276,13 +412,13 @@ - } - } - #endif -- if (tcc_state->leading_underscore && can_add_underscore) { -+ if (st->leading_underscore && can_add_underscore) { - buf1[0] = '_'; -- pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); -+ pstrcpy(st, buf1 + 1, sizeof(buf1) - 1, name); - name = buf1; - } - info = ELF32_ST_INFO(sym_bind, sym_type); -- sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name); -+ sym->c = add_elf_sym(st, symtab_section, value, size, info, 0, sh_num, name); - } else { - esym = &((Elf32_Sym *)symtab_section->data)[sym->c]; - esym->st_value = value; -@@ -1291,39 +427,39 @@ - } - } - --static void put_extern_sym(Sym *sym, Section *section, -+static void put_extern_sym(TCCState * st, Sym *sym, Section *section, - unsigned long value, unsigned long size) - { -- put_extern_sym2(sym, section, value, size, 1); -+ put_extern_sym2(st, sym, section, value, size, 1); - } - - /* add a new relocation entry to symbol 'sym' in section 's' */ --static void greloc(Section *s, Sym *sym, unsigned long offset, int type) -+static void greloc(TCCState * st, Section *s, Sym *sym, unsigned long offset, int type) - { - if (!sym->c) -- put_extern_sym(sym, NULL, 0, 0); -+ put_extern_sym(st, sym, NULL, 0, 0); - /* now we can add ELF relocation info */ -- put_elf_reloc(symtab_section, s, offset, type, sym->c); -+ put_elf_reloc(st, symtab_section, s, offset, type, sym->c); - } - --static inline int isid(int c) -+static inline int isid(TCCState *st, int c) - { - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - c == '_'; - } - --static inline int isnum(int c) -+static inline int isnum(TCCState *st, int c) - { - return c >= '0' && c <= '9'; - } - --static inline int isoct(int c) -+static inline int isoct(TCCState *st, int c) - { - return c >= '0' && c <= '7'; - } - --static inline int toup(int c) -+static inline int toup(TCCState *st, int c) - { - if (c >= 'a' && c <= 'z') - return c - 'a' + 'A'; -@@ -1331,54 +467,54 @@ - return c; - } - --static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) -+static void strcat_vprintf(TCCState *st, char *buf, int buf_size, const char *fmt, va_list ap) - { - int len; - len = strlen(buf); - vsnprintf(buf + len, buf_size - len, fmt, ap); - } - --static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) -+static void strcat_printf(TCCState *st, char *buf, int buf_size, const char *fmt, ...) - { - va_list ap; - va_start(ap, fmt); -- strcat_vprintf(buf, buf_size, fmt, ap); -+ strcat_vprintf(st, buf, buf_size, fmt, ap); - va_end(ap); - } - --void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) -+void error1(TCCState *st, int is_warning, const char *fmt, va_list ap) - { - char buf[2048]; - BufferedFile **f; - - buf[0] = '\0'; - if (file) { -- for(f = s1->include_stack; f < s1->include_stack_ptr; f++) -- strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", -+ for(f = st->include_stack; f < st->include_stack_ptr; f++) -+ strcat_printf(st, buf, sizeof(buf), "In file included from %s:%d:\n", - (*f)->filename, (*f)->line_num); - if (file->line_num > 0) { -- strcat_printf(buf, sizeof(buf), -+ strcat_printf(st, buf, sizeof(buf), - "%s:%d: ", file->filename, file->line_num); - } else { -- strcat_printf(buf, sizeof(buf), -+ strcat_printf(st, buf, sizeof(buf), - "%s: ", file->filename); - } - } else { -- strcat_printf(buf, sizeof(buf), -+ strcat_printf(st, buf, sizeof(buf), - "tcc: "); - } - if (is_warning) -- strcat_printf(buf, sizeof(buf), "warning: "); -- strcat_vprintf(buf, sizeof(buf), fmt, ap); -+ strcat_printf(st, buf, sizeof(buf), "warning: "); -+ strcat_vprintf(st, buf, sizeof(buf), fmt, ap); - -- if (!s1->error_func) { -+ if (!st->error_func) { - /* default case: stderr */ - fprintf(stderr, "%s\n", buf); - } else { -- s1->error_func(s1->error_opaque, buf); -+ st->error_func(st->error_opaque, buf); - } -- if (!is_warning || s1->warn_error) -- s1->nb_errors++; -+ if (!is_warning || st->warn_error) -+ st->nb_errors++; - } - - #ifdef LIBTCC -@@ -1391,83 +527,80 @@ - #endif - - /* error without aborting current compilation */ --void error_noabort(const char *fmt, ...) -+void error_noabort(TCCState * st, const char *fmt, ...) - { -- TCCState *s1 = tcc_state; - va_list ap; - - va_start(ap, fmt); -- error1(s1, 0, fmt, ap); -+ error1(st, 0, fmt, ap); - va_end(ap); - } - --void error(const char *fmt, ...) -+void tcc_error(TCCState * st, const char *fmt, ...) - { -- TCCState *s1 = tcc_state; - va_list ap; - - va_start(ap, fmt); -- error1(s1, 0, fmt, ap); -+ error1(st, 0, fmt, ap); - va_end(ap); - /* better than nothing: in some cases, we accept to handle errors */ -- if (s1->error_set_jmp_enabled) { -- longjmp(s1->error_jmp_buf, 1); -+ if (st->error_set_jmp_enabled) { -+ longjmp(st->error_jmp_buf, 1); - } else { - /* XXX: eliminate this someday */ - exit(1); - } - } - --void expect(const char *msg) -+void expect(TCCState * st, const char *msg) - { -- error("%s expected", msg); -+ tcc_error(st, "%s expected", msg); - } - --void warning(const char *fmt, ...) -+void warning(TCCState * st, const char *fmt, ...) - { -- TCCState *s1 = tcc_state; - va_list ap; - -- if (s1->warn_none) -+ if (st->warn_none) - return; - - va_start(ap, fmt); -- error1(s1, 1, fmt, ap); -+ error1(st, 1, fmt, ap); - va_end(ap); - } - --void skip(int c) -+void skip(TCCState *st, int c) - { - if (tok != c) -- error("'%c' expected", c); -- next(); -+ tcc_error(st,"'%c' expected", c); -+ next(st); - } - --static void test_lvalue(void) -+static void test_lvalue(TCCState *st) - { - if (!(vtop->r & VT_LVAL)) -- expect("lvalue"); -+ expect(st, "lvalue"); - } - - /* allocate a new token */ --static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) -+static TokenSym *tok_alloc_new(TCCState *st, TokenSym **pts, const char *str, int len) - { - TokenSym *ts, **ptable; - int i; - - if (tok_ident >= SYM_FIRST_ANOM) -- error("memory full"); -+ tcc_error(st, "memory full"); - - /* expand token table if needed */ - i = tok_ident - TOK_IDENT; - if ((i % TOK_ALLOC_INCR) == 0) { -- ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *)); -+ ptable = tcc_realloc(st, table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *)); - if (!ptable) -- error("memory full"); -+ tcc_error(st, "memory full"); - table_ident = ptable; - } - -- ts = tcc_malloc(sizeof(TokenSym) + len); -+ ts = tcc_malloc(st, sizeof(TokenSym) + len); - table_ident[i] = ts; - ts->tok = tok_ident++; - ts->sym_define = NULL; -@@ -1486,7 +619,7 @@ - #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c)) - - /* find a token and add it if not found */ --static TokenSym *tok_alloc(const char *str, int len) -+static TokenSym *tok_alloc(TCCState *st, const char *str, int len) - { - TokenSym *ts, **pts; - int i; -@@ -1506,12 +639,12 @@ - return ts; - pts = &(ts->hash_next); - } -- return tok_alloc_new(pts, str, len); -+ return tok_alloc_new(st, pts, str, len); - } - - /* CString handling */ - --static void cstr_realloc(CString *cstr, int new_size) -+static void cstr_realloc(TCCState *st, CString *cstr, int new_size) - { - int size; - void *data; -@@ -1521,86 +654,86 @@ - size = 8; /* no need to allocate a too small first string */ - while (size < new_size) - size = size * 2; -- data = tcc_realloc(cstr->data_allocated, size); -+ data = tcc_realloc(st, cstr->data_allocated, size); - if (!data) -- error("memory full"); -+ tcc_error(st, "memory full"); - cstr->data_allocated = data; - cstr->size_allocated = size; - cstr->data = data; - } - - /* add a byte */ --static inline void cstr_ccat(CString *cstr, int ch) -+static inline void cstr_ccat(TCCState *st,CString *cstr, int ch) - { - int size; - size = cstr->size + 1; - if (size > cstr->size_allocated) -- cstr_realloc(cstr, size); -+ cstr_realloc(st, cstr, size); - ((unsigned char *)cstr->data)[size - 1] = ch; - cstr->size = size; - } - --static void cstr_cat(CString *cstr, const char *str) -+static void cstr_cat(TCCState *st, CString *cstr, const char *str) - { - int c; - for(;;) { - c = *str; - if (c == '\0') - break; -- cstr_ccat(cstr, c); -+ cstr_ccat(st, cstr, c); - str++; - } - } - - /* add a wide char */ --static void cstr_wccat(CString *cstr, int ch) -+static void cstr_wccat(TCCState *st, CString *cstr, int ch) - { - int size; -- size = cstr->size + sizeof(int); -+ size = cstr->size + sizeof(nwchar_t); - if (size > cstr->size_allocated) -- cstr_realloc(cstr, size); -- *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch; -+ cstr_realloc(st, cstr, size); -+ *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch; - cstr->size = size; - } - --static void cstr_new(CString *cstr) -+static void cstr_new(TCCState *st, CString *cstr) - { - memset(cstr, 0, sizeof(CString)); - } - - /* free string and reset it to NULL */ --static void cstr_free(CString *cstr) -+static void cstr_free(TCCState *st, CString *cstr) - { -- tcc_free(cstr->data_allocated); -- cstr_new(cstr); -+ ckfree((char *)(cstr->data_allocated)); -+ cstr_new(st, cstr); - } - --#define cstr_reset(cstr) cstr_free(cstr) -+#define cstr_reset(ts, cstr) cstr_free(ts, cstr) - - /* XXX: unicode ? */ --static void add_char(CString *cstr, int c) -+static void add_char(TCCState *st, CString *cstr, int c) - { - if (c == '\'' || c == '\"' || c == '\\') { - /* XXX: could be more precise if char or string */ -- cstr_ccat(cstr, '\\'); -+ cstr_ccat(st, cstr, '\\'); - } - if (c >= 32 && c <= 126) { -- cstr_ccat(cstr, c); -+ cstr_ccat(st, cstr, c); - } else { -- cstr_ccat(cstr, '\\'); -+ cstr_ccat(st, cstr, '\\'); - if (c == '\n') { -- cstr_ccat(cstr, 'n'); -+ cstr_ccat(st, cstr, 'n'); - } else { -- cstr_ccat(cstr, '0' + ((c >> 6) & 7)); -- cstr_ccat(cstr, '0' + ((c >> 3) & 7)); -- cstr_ccat(cstr, '0' + (c & 7)); -+ cstr_ccat(st, cstr, '0' + ((c >> 6) & 7)); -+ cstr_ccat(st, cstr, '0' + ((c >> 3) & 7)); -+ cstr_ccat(st, cstr, '0' + (c & 7)); - } - } - } - - /* XXX: buffer overflow */ - /* XXX: float tokens */ --char *get_tok_str(int v, CValue *cv) -+char *get_tok_str(TCCState *st, int v, CValue *cv) - { - static char buf[STRING_MAX_SIZE + 1]; - static CString cstr_buf; -@@ -1610,7 +743,7 @@ - int i, len; - - /* NOTE: to go faster, we give a fixed buffer for small strings */ -- cstr_reset(&cstr_buf); -+ cstr_reset(st, &cstr_buf); - cstr_buf.data = buf; - cstr_buf.size_allocated = sizeof(buf); - p = buf; -@@ -1628,33 +761,33 @@ - break; - case TOK_CCHAR: - case TOK_LCHAR: -- cstr_ccat(&cstr_buf, '\''); -- add_char(&cstr_buf, cv->i); -- cstr_ccat(&cstr_buf, '\''); -- cstr_ccat(&cstr_buf, '\0'); -+ cstr_ccat(st, &cstr_buf, '\''); -+ add_char(st, &cstr_buf, cv->i); -+ cstr_ccat(st, &cstr_buf, '\''); -+ cstr_ccat(st, &cstr_buf, '\0'); - break; - case TOK_PPNUM: - cstr = cv->cstr; - len = cstr->size - 1; - for(i=0;idata)[i]); -- cstr_ccat(&cstr_buf, '\0'); -+ add_char(st, &cstr_buf, ((unsigned char *)cstr->data)[i]); -+ cstr_ccat(st, &cstr_buf, '\0'); - break; - case TOK_STR: - case TOK_LSTR: - cstr = cv->cstr; -- cstr_ccat(&cstr_buf, '\"'); -+ cstr_ccat(st, &cstr_buf, '\"'); - if (v == TOK_STR) { - len = cstr->size - 1; - for(i=0;idata)[i]); -+ add_char(st, &cstr_buf, ((unsigned char *)cstr->data)[i]); - } else { -- len = (cstr->size / sizeof(int)) - 1; -+ len = (cstr->size / sizeof(nwchar_t)) - 1; - for(i=0;idata)[i]); -+ add_char(st, &cstr_buf, ((nwchar_t *)cstr->data)[i]); - } -- cstr_ccat(&cstr_buf, '\"'); -- cstr_ccat(&cstr_buf, '\0'); -+ cstr_ccat(st, &cstr_buf, '\"'); -+ cstr_ccat(st, &cstr_buf, '\0'); - break; - case TOK_LT: - v = '<'; -@@ -1662,6 +795,8 @@ - case TOK_GT: - v = '>'; - goto addv; -+ case TOK_DOTS: -+ return strcpy(p, "..."); - case TOK_A_SHL: - return strcpy(p, "<<="); - case TOK_A_SAR: -@@ -1697,10 +832,10 @@ - } - - /* push, without hashing */ --static Sym *sym_push2(Sym **ps, int v, int t, int c) -+static Sym *sym_push2(TCCState *st, Sym **ps, int v, int t, int c) - { - Sym *s; -- s = sym_malloc(); -+ s = sym_malloc(st); - s->v = v; - s->type.t = t; - s->c = c; -@@ -1713,7 +848,7 @@ - - /* find a symbol and return its associated structure. 's' is the top - of the symbol stack */ --static Sym *sym_find2(Sym *s, int v) -+static Sym *sym_find2(TCCState *st, Sym *s, int v) - { - while (s) { - if (s->v == v) -@@ -1724,7 +859,7 @@ - } - - /* structure lookup */ --static inline Sym *struct_find(int v) -+static inline Sym *struct_find(TCCState *st, int v) - { - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) -@@ -1733,7 +868,7 @@ - } - - /* find an identifier */ --static inline Sym *sym_find(int v) -+static inline Sym *sym_find(TCCState *st, int v) - { - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) -@@ -1742,7 +877,7 @@ - } - - /* push a given symbol on the symbol stack */ --static Sym *sym_push(int v, CType *type, int r, int c) -+static Sym *sym_push(TCCState *st, int v, CType *type, int r, int c) - { - Sym *s, **ps; - TokenSym *ts; -@@ -1751,7 +886,7 @@ - ps = &local_stack; - else - ps = &global_stack; -- s = sym_push2(ps, v, type->t, c); -+ s = sym_push2(st, ps, v, type->t, c); - s->type.ref = type->ref; - s->r = r; - /* don't record fields or anonymous symbols */ -@@ -1770,10 +905,10 @@ - } - - /* push a global identifier */ --static Sym *global_identifier_push(int v, int t, int c) -+static Sym *global_identifier_push(TCCState *st, int v, int t, int c) - { - Sym *s, **ps; -- s = sym_push2(&global_stack, v, t, c); -+ s = sym_push2(st, &global_stack, v, t, c); - /* don't record anonymous symbol */ - if (v < SYM_FIRST_ANOM) { - ps = &table_ident[v - TOK_IDENT]->sym_identifier; -@@ -1788,7 +923,7 @@ - } - - /* pop symbols until top reaches 'b' */ --static void sym_pop(Sym **ptop, Sym *b) -+static void sym_pop(TCCState *st, Sym **ptop, Sym *b) - { - Sym *s, *ss, **ps; - TokenSym *ts; -@@ -1808,7 +943,7 @@ - ps = &ts->sym_identifier; - *ps = s->prev_tok; - } -- sym_free(s); -+ sym_free(st, s); - s = ss; - } - *ptop = b; -@@ -1816,51 +951,62 @@ - - /* I/O layer */ - --BufferedFile *tcc_open(TCCState *s1, const char *filename) -+BufferedFile *tcc_open(TCCState *st, const char *filename) - { -- int fd; -+ Tcl_Channel fd; - BufferedFile *bf; -- -- fd = open(filename, O_RDONLY | O_BINARY); -- if (fd < 0) -+ int i, len; -+ /*printf("opening '%s'\n", filename); */ -+ Tcl_Obj * path ; -+ path = Tcl_NewStringObj(filename,-1); -+ Tcl_IncrRefCount(path); -+ fd = Tcl_FSOpenFileChannel(NULL,path, "r", 0); -+ Tcl_DecrRefCount(path); -+ if (fd==NULL) { -+ /*printf("T_FOFC, returned NULL\n"); */ - return NULL; -- bf = tcc_malloc(sizeof(BufferedFile)); -+ } -+ /*printf("T_FOFC, returned SUCCESS\n"); */ -+ bf = tcc_malloc(st, sizeof(BufferedFile)); - if (!bf) { -- close(fd); -+ Tcl_Close(NULL,fd); - return NULL; - } - bf->fd = fd; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer; - bf->buffer[0] = CH_EOB; /* put eob symbol */ -- pstrcpy(bf->filename, sizeof(bf->filename), filename); -+ pstrcpy(st, bf->filename, sizeof(bf->filename), filename); -+ len = strlen(bf->filename); -+ for (i = 0; i < len; i++) -+ if (bf->filename[i] == '\\') -+ bf->filename[i] = '/'; - bf->line_num = 1; - bf->ifndef_macro = 0; -- bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; -- // printf("opening '%s'\n", filename); -+ bf->ifdef_stack_ptr = st->ifdef_stack_ptr; - return bf; - } - - void tcc_close(BufferedFile *bf) - { - total_lines += bf->line_num; -- close(bf->fd); -- tcc_free(bf); -+ Tcl_Close(NULL,bf->fd); -+ ckfree((char *)bf); - } - - /* fill input buffer and peek next char */ --static int tcc_peekc_slow(BufferedFile *bf) -+static int tcc_peekc_slow(TCCState *st, BufferedFile *bf) - { - int len; - /* only tries to read if really end of buffer */ - if (bf->buf_ptr >= bf->buf_end) { -- if (bf->fd != -1) { -+ if (bf->fd != NULL) { - #if defined(PARSE_DEBUG) - len = 8; - #else - len = IO_BUF_SIZE; - #endif -- len = read(bf->fd, bf->buffer, len); -+ len = Tcl_Read(bf->fd, bf->buffer, len); - if (len < 0) - len = 0; - } else { -@@ -1881,58 +1027,63 @@ - - /* return the current character, handling end of block if necessary - (but not stray) */ --static int handle_eob(void) -+static int handle_eob(TCCState *st) - { -- return tcc_peekc_slow(file); -+ return tcc_peekc_slow(st, file); - } - - /* read next char from current input file and handle end of input buffer */ --static inline void inp(void) -+static inline void inp(TCCState *st) - { -- ch = *(++(file->buf_ptr)); -+ fch = *(++(file->buf_ptr)); - /* end of buffer/file handling */ -- if (ch == CH_EOB) -- ch = handle_eob(); -+ if (fch == CH_EOB) -+ fch = handle_eob(st); -+} -+ -+/* space excluding newline */ -+static inline int is_space(TCCState *st, int ch) -+{ -+ return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; - } - - /* handle '\[\r]\n' */ --static void handle_stray(void) -+static int handle_stray_noerror(TCCState *st) - { -- while (ch == '\\') { -- inp(); -- if (ch == '\n') { -- file->line_num++; -- inp(); -- } else if (ch == '\r') { -- inp(); -- if (ch != '\n') -- goto fail; -+ while (fch == '\\') { -+ inp(st); -+ while (is_space(st, fch)) inp(st); -+ if (fch == '\n') { - file->line_num++; -- inp(); -- } else { -- fail: -- error("stray '\\' in program"); -+ inp(st); -+ } else return 1; - } -+ return 0; - } -+ -+static void handle_stray(TCCState *st) -+{ -+ if(handle_stray_noerror(st)) -+ tcc_error(st, "stray '\\' in program"); - } - - /* skip the stray and handle the \\n case. Output an error if - incorrect char after the stray */ --static int handle_stray1(uint8_t *p) -+static int handle_stray1(TCCState *st, uint8_t *p) - { - int c; - - if (p >= file->buf_end) { - file->buf_ptr = p; -- c = handle_eob(); -+ c = handle_eob(st); - p = file->buf_ptr; - if (c == '\\') - goto parse_stray; - } else { - parse_stray: - file->buf_ptr = p; -- ch = *p; -- handle_stray(); -+ fch = *p; -+ handle_stray(st); - p = file->buf_ptr; - c = *p; - } -@@ -1940,24 +1091,24 @@ - } - - /* handle just the EOB case, but not stray */ --#define PEEKC_EOB(c, p)\ -+#define PEEKC_EOB(st, c, p)\ - {\ - p++;\ - c = *p;\ - if (c == '\\') {\ - file->buf_ptr = p;\ -- c = handle_eob();\ -+ c = handle_eob(st);\ - p = file->buf_ptr;\ - }\ - } - - /* handle the complicated stray case */ --#define PEEKC(c, p)\ -+#define PEEKC(st, c, p)\ - {\ - p++;\ - c = *p;\ - if (c == '\\') {\ -- c = handle_stray1(p);\ -+ c = handle_stray1(st, p);\ - p = file->buf_ptr;\ - }\ - } -@@ -1965,16 +1116,16 @@ - /* input with '\[\r]\n' handling. Note that this function cannot - handle other characters after '\', so you cannot call it inside - strings or comments */ --static void minp(void) -+static void minp(TCCState *st) - { -- inp(); -- if (ch == '\\') -- handle_stray(); -+ inp(st); -+ if (fch == '\\') -+ handle_stray(st); - } - - - /* single line C++ comments */ --static uint8_t *parse_line_comment(uint8_t *p) -+static uint8_t *parse_line_comment(TCCState *st, uint8_t *p) - { - int c; - -@@ -1986,18 +1137,18 @@ - break; - } else if (c == '\\') { - file->buf_ptr = p; -- c = handle_eob(); -+ c = handle_eob(st); - p = file->buf_ptr; - if (c == '\\') { -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c == '\n') { - file->line_num++; -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - } else if (c == '\r') { -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c == '\n') { - file->line_num++; -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - } - } - } else { -@@ -2011,7 +1162,7 @@ - } - - /* C comments */ --static uint8_t *parse_comment(uint8_t *p) -+static uint8_t *parse_comment(TCCState *st, uint8_t *p) - { - int c; - -@@ -2042,20 +1193,20 @@ - goto end_of_comment; - } else if (c == '\\') { - file->buf_ptr = p; -- c = handle_eob(); -+ c = handle_eob(st); - p = file->buf_ptr; - if (c == '\\') { - /* skip '\[\r]\n', otherwise just skip the stray */ - while (c == '\\') { -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c == '\n') { - file->line_num++; -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - } else if (c == '\r') { -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c == '\n') { - file->line_num++; -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - } - } else { - goto after_star; -@@ -2070,10 +1221,10 @@ - } else { - /* stray, eob or eof */ - file->buf_ptr = p; -- c = handle_eob(); -+ c = handle_eob(st); - p = file->buf_ptr; - if (c == CH_EOF) { -- error("unexpected end of file in comment"); -+ tcc_error(st, "unexpected end of file in comment"); - } else if (c == '\\') { - p++; - } -@@ -2086,20 +1237,14 @@ - - #define cinp minp - --/* space exlcuding newline */ --static inline int is_space(int ch) --{ -- return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; --} -- --static inline void skip_spaces(void) -+static inline void skip_spaces(TCCState *st) - { -- while (is_space(ch)) -- cinp(); -+ while (is_space(st, fch)) -+ cinp(st); - } - - /* parse a string without interpreting escapes */ --static uint8_t *parse_pp_string(uint8_t *p, -+static uint8_t *parse_pp_string(TCCState *st, uint8_t *p, - int sep, CString *str) - { - int c; -@@ -2110,30 +1255,30 @@ - break; - } else if (c == '\\') { - file->buf_ptr = p; -- c = handle_eob(); -+ c = handle_eob(st); - p = file->buf_ptr; - if (c == CH_EOF) { - unterminated_string: - /* XXX: indicate line number of start of string */ -- error("missing terminating %c character", sep); -+ tcc_error(st, "missing terminating %c character", sep); - } else if (c == '\\') { - /* escape : just skip \[\r]\n */ -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c == '\n') { - file->line_num++; - p++; - } else if (c == '\r') { -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c != '\n') -- expect("'\n' after '\r'"); -+ expect(st, "'\n' after '\r'"); - file->line_num++; - p++; - } else if (c == CH_EOF) { - goto unterminated_string; - } else { - if (str) { -- cstr_ccat(str, '\\'); -- cstr_ccat(str, c); -+ cstr_ccat(st, str, '\\'); -+ cstr_ccat(st, str, c); - } - p++; - } -@@ -2142,10 +1287,10 @@ - file->line_num++; - goto add_char; - } else if (c == '\r') { -- PEEKC_EOB(c, p); -+ PEEKC_EOB(st, c, p); - if (c != '\n') { - if (str) -- cstr_ccat(str, '\r'); -+ cstr_ccat(st, str, '\r'); - } else { - file->line_num++; - goto add_char; -@@ -2153,7 +1298,7 @@ - } else { - add_char: - if (str) -- cstr_ccat(str, c); -+ cstr_ccat(st, str, c); - p++; - } - } -@@ -2163,7 +1308,7 @@ - - /* skip block of text until #else, #elif or #endif. skip also pairs of - #if/#endif */ --void preprocess_skip(void) -+void preprocess_skip(TCCState *st) - { - int a, start_of_line, c; - uint8_t *p; -@@ -2189,31 +1334,30 @@ - goto redo_no_start; - case '\\': - file->buf_ptr = p; -- c = handle_eob(); -+ c = handle_eob(st); - if (c == CH_EOF) { -- expect("#endif"); -+ expect(st, "#endif"); - } else if (c == '\\') { -- /* XXX: incorrect: should not give an error */ -- ch = file->buf_ptr[0]; -- handle_stray(); -+ fch = file->buf_ptr[0]; -+ handle_stray_noerror(st); - } - p = file->buf_ptr; - goto redo_no_start; - /* skip strings */ - case '\"': - case '\'': -- p = parse_pp_string(p, c, NULL); -+ p = parse_pp_string(st, p, c, NULL); - break; - /* skip comments */ - case '/': - file->buf_ptr = p; -- ch = *p; -- minp(); -+ fch = *p; -+ minp(st); - p = file->buf_ptr; -- if (ch == '*') { -- p = parse_comment(p); -- } else if (ch == '/') { -- p = parse_line_comment(p); -+ if (fch == '*') { -+ p = parse_comment(st, p); -+ } else if (fch == '/') { -+ p = parse_line_comment(st, p); - } - break; - -@@ -2221,7 +1365,7 @@ - p++; - if (start_of_line) { - file->buf_ptr = p; -- next_nomacro(); -+ next_nomacro(st); - p = file->buf_ptr; - if (a == 0 && - (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF)) -@@ -2249,7 +1393,7 @@ - files */ - - /* save current parse state in 's' */ --void save_parse_state(ParseState *s) -+void save_parse_state(TCCState *st, ParseState *s) - { - s->line_num = file->line_num; - s->macro_ptr = macro_ptr; -@@ -2258,7 +1402,7 @@ - } - - /* restore parse state from 's' */ --void restore_parse_state(ParseState *s) -+void restore_parse_state(TCCState *st, ParseState *s) - { - file->line_num = s->line_num; - macro_ptr = s->macro_ptr; -@@ -2268,7 +1412,7 @@ - - /* return the number of additional 'ints' necessary to store the - token */ --static inline int tok_ext_size(int t) -+static inline int tok_ext_size(TCCState *st, int t) - { - switch(t) { - /* 4 bytes */ -@@ -2282,7 +1426,7 @@ - case TOK_STR: - case TOK_LSTR: - case TOK_PPNUM: -- error("unsupported token"); -+ tcc_error(st,"unsupported token"); - return 1; - case TOK_CDOUBLE: - case TOK_CLLONG: -@@ -2297,7 +1441,7 @@ - - /* token string handling */ - --static inline void tok_str_new(TokenString *s) -+static inline void tok_str_new(TCCState *st, TokenString *s) - { - s->str = NULL; - s->len = 0; -@@ -2305,12 +1449,12 @@ - s->last_line_num = -1; - } - --static void tok_str_free(int *str) -+static void tok_str_free(TCCState *st, int *str) - { -- tcc_free(str); -+ ckfree((char *)str); - } - --static int *tok_str_realloc(TokenString *s) -+static int *tok_str_realloc(TCCState *st, TokenString *s) - { - int *str, len; - -@@ -2319,27 +1463,28 @@ - } else { - len = s->allocated_len * 2; - } -- str = tcc_realloc(s->str, len * sizeof(int)); -+ str = tcc_realloc(st, s->str, len * sizeof(int)); - if (!str) -- error("memory full"); -+ tcc_error(st, "memory full"); - s->allocated_len = len; - s->str = str; - return str; - } - --static void tok_str_add(TokenString *s, int t) -+static void tok_str_add(TCCState *st, TokenString *s, int t, int tf) - { - int len, *str; - - len = s->len; - str = s->str; -- if (len >= s->allocated_len) -- str = tok_str_realloc(s); -+ if (len+1 >= s->allocated_len) -+ str = tok_str_realloc(st, s); - str[len++] = t; -+ str[len++] = tf; - s->len = len; - } - --static void tok_str_add2(TokenString *s, int t, CValue *cv) -+static void tok_str_add2(TCCState *st, TokenString *s, int t, int tf, CValue *cv) - { - int len, *str; - -@@ -2348,8 +1493,9 @@ - - /* allocate space for worst case */ - if (len + TOK_MAX_SIZE > s->allocated_len) -- str = tok_str_realloc(s); -+ str = tok_str_realloc(st, s); - str[len++] = t; -+ str[len++] = tf; - switch(t) { - case TOK_CINT: - case TOK_CUINT: -@@ -2368,7 +1514,7 @@ - - nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2; - while ((len + nb_words) > s->allocated_len) -- str = tok_str_realloc(s); -+ str = tok_str_realloc(st, s); - cstr = (CString *)(str + len); - cstr->data = NULL; - cstr->size = cv->cstr->size; -@@ -2404,7 +1550,7 @@ - } - - /* add the current parse token in token string 's' */ --static void tok_str_add_tok(TokenString *s) -+static void tok_str_add_tok(TCCState *st, TokenString *s) - { - CValue cval; - -@@ -2412,18 +1558,18 @@ - if (file->line_num != s->last_line_num) { - s->last_line_num = file->line_num; - cval.i = s->last_line_num; -- tok_str_add2(s, TOK_LINENUM, &cval); -+ tok_str_add2(st, s, TOK_LINENUM, 0, &cval); - } -- tok_str_add2(s, tok, &tokc); -+ tok_str_add2(st, s, tok, tok_flags, &tokc); - } - - #if LDOUBLE_SIZE == 12 --#define LDOUBLE_GET(p, cv) \ -+#define LDOUBLE_GET(st, p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - cv.tab[2] = p[2]; - #elif LDOUBLE_SIZE == 8 --#define LDOUBLE_GET(p, cv) \ -+#define LDOUBLE_GET(st, p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; - #else -@@ -2433,9 +1579,10 @@ - - /* get a token from an integer array and increment pointer - accordingly. we code it as a macro to avoid pointer aliasing. */ --#define TOK_GET(t, p, cv) \ -+#define TOK_GET(t, tf, p, cv) \ - { \ - t = *p++; \ -+ tf = *p++; \ - switch(t) { \ - case TOK_CINT: \ - case TOK_CUINT: \ -@@ -2460,7 +1607,7 @@ - p += 2; \ - break; \ - case TOK_CLDOUBLE: \ -- LDOUBLE_GET(p, cv); \ -+ LDOUBLE_GET(st, p, cv); \ - p += LDOUBLE_SIZE / 4; \ - break; \ - default: \ -@@ -2469,11 +1616,11 @@ - } - - /* defines handling */ --static inline void define_push(int v, int macro_type, int *str, Sym *first_arg) -+static inline void define_push(TCCState *st, int v, int macro_type, int *str, Sym *first_arg) - { - Sym *s; - -- s = sym_push2(&define_stack, v, macro_type, (int)str); -+ s = sym_push2(st, &define_stack, v, macro_type, (int)str); - s->next = first_arg; - table_ident[v - TOK_IDENT]->sym_define = s; - } -@@ -2488,7 +1635,7 @@ - s->v = 0; - } - --static inline Sym *define_find(int v) -+static inline Sym *define_find(TCCState *st, int v) - { - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) -@@ -2497,7 +1644,7 @@ - } - - /* free define stack until top reaches 'b' */ --static void free_defines(Sym *b) -+static void free_defines(TCCState *st, Sym *b) - { - Sym *top, *top1; - int v; -@@ -2507,18 +1654,18 @@ - top1 = top->prev; - /* do not free args or predefined defines */ - if (top->c) -- tok_str_free((int *)top->c); -+ tok_str_free(st, (int *)top->c); - v = top->v; - if (v >= TOK_IDENT && v < tok_ident) - table_ident[v - TOK_IDENT]->sym_define = NULL; -- sym_free(top); -+ sym_free(st, top); - top = top1; - } - define_stack = b; - } - - /* label lookup */ --static Sym *label_find(int v) -+static Sym *label_find(TCCState *st, int v) - { - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) -@@ -2526,10 +1673,10 @@ - return table_ident[v]->sym_label; - } - --static Sym *label_push(Sym **ptop, int v, int flags) -+static Sym *label_push(TCCState *st, Sym **ptop, int v, int flags) - { - Sym *s, **ps; -- s = sym_push2(ptop, v, 0, 0); -+ s = sym_push2(st, ptop, v, 0, 0); - s->r = flags; - ps = &table_ident[v - TOK_IDENT]->sym_label; - if (ptop == &global_label_stack) { -@@ -2545,47 +1692,47 @@ - - /* pop labels until element last is reached. Look if any labels are - undefined. Define symbols if '&&label' was used. */ --static void label_pop(Sym **ptop, Sym *slast) -+static void label_pop(TCCState * state, Sym **ptop, Sym *slast) - { -- Sym *s, *s1; -- for(s = *ptop; s != slast; s = s1) { -- s1 = s->prev; -+ Sym *s, *st; -+ for(s = *ptop; s != slast; s = st) { -+ st = s->prev; - if (s->r == LABEL_DECLARED) { -- warning("label '%s' declared but not used", get_tok_str(s->v, NULL)); -+ warning(state, "label '%s' declared but not used", get_tok_str(state, s->v, NULL)); - } else if (s->r == LABEL_FORWARD) { -- error("label '%s' used but not defined", -- get_tok_str(s->v, NULL)); -+ tcc_error(state, "label '%s' used but not defined", -+ get_tok_str(state, s->v, NULL)); - } else { - if (s->c) { - /* define corresponding symbol. A size of - 1 is put. */ -- put_extern_sym(s, cur_text_section, (long)s->next, 1); -+ put_extern_sym(state, s, cur_text_section, (long)s->next, 1); - } - } - /* remove label */ - table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; -- sym_free(s); -+ sym_free(state, s); - } - *ptop = slast; - } - - /* eval an expression for #if/#elif */ --static int expr_preprocess(void) -+static int expr_preprocess(TCCState *st) - { - int c, t; - TokenString str; - -- tok_str_new(&str); -+ tok_str_new(st, &str); - while (tok != TOK_LINEFEED && tok != TOK_EOF) { -- next(); /* do macro subst */ -+ next(st); /* do macro subst */ - if (tok == TOK_DEFINED) { -- next_nomacro(); -+ next_nomacro(st); - t = tok; - if (t == '(') -- next_nomacro(); -- c = define_find(tok) != 0; -+ next_nomacro(st); -+ c = define_find(st, tok) != 0; - if (t == '(') -- next_nomacro(); -+ next_nomacro(st); - tok = TOK_CINT; - tokc.i = c; - } else if (tok >= TOK_IDENT) { -@@ -2593,37 +1740,37 @@ - tok = TOK_CINT; - tokc.i = 0; - } -- tok_str_add_tok(&str); -+ tok_str_add_tok(st, &str); - } -- tok_str_add(&str, -1); /* simulate end of file */ -- tok_str_add(&str, 0); -+ tok_str_add(st, &str, -1, 0); /* simulate end of file */ -+ tok_str_add(st, &str, 0, 0); - /* now evaluate C constant expression */ - macro_ptr = str.str; -- next(); -- c = expr_const(); -+ next(st); -+ c = expr_const(st); - macro_ptr = NULL; -- tok_str_free(str.str); -+ tok_str_free(st, str.str); - return c != 0; - } - - #if defined(PARSE_DEBUG) || defined(PP_DEBUG) --static void tok_print(int *str) -+static void tok_print(TCCState *st, int *str) - { -- int t; -+ int t, tf; - CValue cval; - - while (1) { -- TOK_GET(t, str, cval); -+ TOK_GET(st, t, tf, str, cval); - if (!t) - break; -- printf(" %s", get_tok_str(t, &cval)); -+ printf(st, " %s", get_tok_str(st, t, &cval)); - } - printf("\n"); - } - #endif - - /* parse after #define */ --static void parse_define(void) -+static void parse_define(TCCState *st) - { - Sym *s, *first, **ps; - int v, t, varg, is_vaargs, c; -@@ -2631,56 +1778,56 @@ - - v = tok; - if (v < TOK_IDENT) -- error("invalid macro name '%s'", get_tok_str(tok, &tokc)); -+ tcc_error(st, "invalid macro name '%s'", get_tok_str(st, tok, &tokc)); - /* XXX: should check if same macro (ANSI) */ - first = NULL; - t = MACRO_OBJ; - /* '(' must be just after macro definition for MACRO_FUNC */ - c = file->buf_ptr[0]; - if (c == '\\') -- c = handle_stray1(file->buf_ptr); -+ c = handle_stray1(st, file->buf_ptr); - if (c == '(') { -- next_nomacro(); -- next_nomacro(); -+ next_nomacro(st); -+ next_nomacro(st); - ps = &first; - while (tok != ')') { - varg = tok; -- next_nomacro(); -+ next_nomacro(st); - is_vaargs = 0; - if (varg == TOK_DOTS) { - varg = TOK___VA_ARGS__; - is_vaargs = 1; - } else if (tok == TOK_DOTS && gnu_ext) { - is_vaargs = 1; -- next_nomacro(); -+ next_nomacro(st); - } - if (varg < TOK_IDENT) -- error("badly punctuated parameter list"); -- s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0); -+ tcc_error(st,"badly punctuated parameter list"); -+ s = sym_push2(st,&define_stack, varg | SYM_FIELD, is_vaargs, 0); - *ps = s; - ps = &s->next; - if (tok != ',') - break; -- next_nomacro(); -+ next_nomacro(st); - } - t = MACRO_FUNC; - } -- tok_str_new(&str); -- next_nomacro(); -+ tok_str_new(st, &str); -+ next_nomacro(st); - /* EOF testing necessary for '-D' handling */ - while (tok != TOK_LINEFEED && tok != TOK_EOF) { -- tok_str_add2(&str, tok, &tokc); -- next_nomacro(); -+ tok_str_add2(st,&str, tok, tok_flags, &tokc); -+ next_nomacro(st); - } -- tok_str_add(&str, 0); -+ tok_str_add(st,&str, 0, 0); - #ifdef PP_DEBUG -- printf("define %s %d: ", get_tok_str(v, NULL), t); -- tok_print(str.str); -+ printf("define %s %d: ", get_tok_str(st,v, NULL), t); -+ tok_print(st, str.str); - #endif -- define_push(v, t, str.str, first); -+ define_push(st, v, t, str.str, first); - } - --static inline int hash_cached_include(int type, const char *filename) -+static inline int hash_cached_include(TCCState *st, int type, const char *filename) - { - const unsigned char *s; - unsigned int h; -@@ -2697,17 +1844,17 @@ - } - - /* XXX: use a token or a hash table to accelerate matching ? */ --static CachedInclude *search_cached_include(TCCState *s1, -+static CachedInclude *search_cached_include(TCCState *st, - int type, const char *filename) - { - CachedInclude *e; - int i, h; -- h = hash_cached_include(type, filename); -- i = s1->cached_includes_hash[h]; -+ h = hash_cached_include(st, type, filename); -+ i = st->cached_includes_hash[h]; - for(;;) { - if (i == 0) - break; -- e = s1->cached_includes[i - 1]; -+ e = st->cached_includes[i - 1]; - if (e->type == type && !strcmp(e->filename, filename)) - return e; - i = e->hash_next; -@@ -2715,81 +1862,80 @@ - return NULL; - } - --static inline void add_cached_include(TCCState *s1, int type, -+static inline void add_cached_include(TCCState *st, int type, - const char *filename, int ifndef_macro) - { - CachedInclude *e; - int h; - -- if (search_cached_include(s1, type, filename)) -+ if (search_cached_include(st, type, filename)) - return; - #ifdef INC_DEBUG -- printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL)); -+ printf("adding cached '%s' %s\n", filename, get_tok_str(st, ifndef_macro, NULL)); - #endif -- e = tcc_malloc(sizeof(CachedInclude) + strlen(filename)); -+ e = tcc_malloc(st, sizeof(CachedInclude) + strlen(filename)); - if (!e) - return; - e->type = type; - strcpy(e->filename, filename); - e->ifndef_macro = ifndef_macro; -- dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e); -+ dynarray_add(st, (void ***)&st->cached_includes, &st->nb_cached_includes, e); - /* add in hash table */ -- h = hash_cached_include(type, filename); -- e->hash_next = s1->cached_includes_hash[h]; -- s1->cached_includes_hash[h] = s1->nb_cached_includes; -+ h = hash_cached_include(st, type, filename); -+ e->hash_next = st->cached_includes_hash[h]; -+ st->cached_includes_hash[h] = st->nb_cached_includes; - } - --static void pragma_parse(TCCState *s1) -+static void pragma_parse(TCCState *st) - { - int val; - -- next(); -+ next(st); - if (tok == TOK_pack) { - /* - This may be: -- #pragma pack(1) // set -- #pragma pack() // reset to default -- #pragma pack(push,1) // push & set -- #pragma pack(pop) // restore previous -+ #pragma pack(1) set -+ #pragma pack() reset to default -+ #pragma pack(push,1) push & set -+ #pragma pack(pop) restore previous - */ -- next(); -- skip('('); -+ next(st); -+ skip(st, '('); - if (tok == TOK_ASM_pop) { -- next(); -- if (s1->pack_stack_ptr <= s1->pack_stack) { -+ next(st); -+ if (st->pack_stack_ptr <= st->pack_stack) { - stk_error: -- error("out of pack stack"); -+ tcc_error(st,"out of pack stack"); - } -- s1->pack_stack_ptr--; -+ st->pack_stack_ptr--; - } else { - val = 0; - if (tok != ')') { - if (tok == TOK_ASM_push) { -- next(); -- if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1) -+ next(st); -+ if (st->pack_stack_ptr >= st->pack_stack + PACK_STACK_SIZE - 1) - goto stk_error; -- s1->pack_stack_ptr++; -- skip(','); -+ st->pack_stack_ptr++; -+ skip(st, ','); - } - if (tok != TOK_CINT) { - pack_error: -- error("invalid pack pragma"); -+ tcc_error(st, "invalid pack pragma"); - } - val = tokc.i; - if (val < 1 || val > 16 || (val & (val - 1)) != 0) - goto pack_error; -- next(); -+ next(st); - } -- *s1->pack_stack_ptr = val; -- skip(')'); -+ *st->pack_stack_ptr = val; -+ skip(st, ')'); - } - } - } - - /* is_bof is true if first non space token at beginning of file */ --static void preprocess(int is_bof) -+static void preprocess(TCCState * st, int is_bof) - { -- TCCState *s1 = tcc_state; - int size, i, c, n, saved_parse_flags; - char buf[1024], *q, *p; - char buf1[1024]; -@@ -2800,67 +1946,67 @@ - saved_parse_flags = parse_flags; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | - PARSE_FLAG_LINEFEED; -- next_nomacro(); -+ next_nomacro(st); - redo: - switch(tok) { - case TOK_DEFINE: -- next_nomacro(); -- parse_define(); -+ next_nomacro(st); -+ parse_define(st); - break; - case TOK_UNDEF: -- next_nomacro(); -- s = define_find(tok); -+ next_nomacro(st); -+ s = define_find(st, tok); - /* undefine symbol by putting an invalid name */ - if (s) - define_undef(s); - break; - case TOK_INCLUDE: - case TOK_INCLUDE_NEXT: -- ch = file->buf_ptr[0]; -+ fch = file->buf_ptr[0]; - /* XXX: incorrect if comments : use next_nomacro with a special mode */ -- skip_spaces(); -- if (ch == '<') { -+ skip_spaces(st); -+ if (fch == '<') { - c = '>'; - goto read_name; -- } else if (ch == '\"') { -- c = ch; -+ } else if (fch == '\"') { -+ c = fch; - read_name: - /* XXX: better stray handling */ -- minp(); -+ minp(st); - q = buf; -- while (ch != c && ch != '\n' && ch != CH_EOF) { -+ while (fch != c && fch != '\n' && fch != CH_EOF) { - if ((q - buf) < sizeof(buf) - 1) -- *q++ = ch; -- minp(); -+ *q++ = fch; -+ minp(st); - } - *q = '\0'; -- minp(); -+ minp(st); - #if 0 - /* eat all spaces and comments after include */ - /* XXX: slightly incorrect */ - while (ch1 != '\n' && ch1 != CH_EOF) -- inp(); -+ inp(st); - #endif - } else { - /* computed #include : either we have only strings or - we have anything enclosed in '<>' */ -- next(); -+ next(st); - buf[0] = '\0'; - if (tok == TOK_STR) { - while (tok != TOK_LINEFEED) { - if (tok != TOK_STR) { - include_syntax: -- error("'#include' expects \"FILENAME\" or "); -+ tcc_error(st,"'#include' expects \"FILENAME\" or "); - } -- pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data); -- next(); -+ pstrcat(st, buf, sizeof(buf), (char *)tokc.cstr->data); -+ next(st); - } - c = '\"'; - } else { - int len; - while (tok != TOK_LINEFEED) { -- pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); -- next(); -+ pstrcat(st, buf, sizeof(buf), get_tok_str(st,tok, &tokc)); -+ next(st); - } - len = strlen(buf); - /* check syntax and remove '<>' */ -@@ -2872,8 +2018,8 @@ - } - } - -- e = search_cached_include(s1, c, buf); -- if (e && define_find(e->ifndef_macro)) { -+ e = search_cached_include(st, c, buf); -+ if (e && define_find(st, e->ifndef_macro)) { - /* no need to parse the include because the 'ifndef macro' - is defined */ - #ifdef INC_DEBUG -@@ -2890,8 +2036,8 @@ - size = sizeof(buf1) - 1; - memcpy(buf1, file->filename, size); - buf1[size] = '\0'; -- pstrcat(buf1, sizeof(buf1), buf); -- f = tcc_open(s1, buf1); -+ pstrcat(st, buf1, sizeof(buf1), buf); -+ f = tcc_open(st, buf1); - if (f) { - if (tok == TOK_INCLUDE_NEXT) - tok = TOK_INCLUDE; -@@ -2899,20 +2045,20 @@ - goto found; - } - } -- if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) -- error("#include recursion too deep"); -+ if (st->include_stack_ptr >= st->include_stack + INCLUDE_STACK_SIZE) -+ tcc_error(st, "#include recursion too deep"); - /* now search in all the include paths */ -- n = s1->nb_include_paths + s1->nb_sysinclude_paths; -+ n = st->nb_include_paths + st->nb_sysinclude_paths; - for(i = 0; i < n; i++) { - const char *path; -- if (i < s1->nb_include_paths) -- path = s1->include_paths[i]; -+ if (i < st->nb_include_paths) -+ path = st->include_paths[i]; - else -- path = s1->sysinclude_paths[i - s1->nb_include_paths]; -- pstrcpy(buf1, sizeof(buf1), path); -- pstrcat(buf1, sizeof(buf1), "/"); -- pstrcat(buf1, sizeof(buf1), buf); -- f = tcc_open(s1, buf1); -+ path = st->sysinclude_paths[i - st->nb_include_paths]; -+ pstrcpy(st, buf1, sizeof(buf1), path); -+ pstrcat(st, buf1, sizeof(buf1), "/"); -+ pstrcat(st, buf1, sizeof(buf1), buf); -+ f = tcc_open(st, buf1); - if (f) { - if (tok == TOK_INCLUDE_NEXT) - tok = TOK_INCLUDE; -@@ -2920,24 +2066,24 @@ - goto found; - } - } -- error("include file '%s' not found", buf); -+ tcc_error(st, "include file '%s' not found", buf); - f = NULL; - found: - #ifdef INC_DEBUG - printf("%s: including %s\n", file->filename, buf1); - #endif - f->inc_type = c; -- pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf); -+ pstrcpy(st, f->inc_filename, sizeof(f->inc_filename), buf); - /* push current file in stack */ - /* XXX: fix current line init */ -- *s1->include_stack_ptr++ = file; -+ *st->include_stack_ptr++ = file; - file = f; - /* add include file debug info */ - if (do_debug) { -- put_stabs(file->filename, N_BINCL, 0, 0, 0); -+ put_stabs(st, file->filename, N_BINCL, 0, 0, 0); - } -- tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; -- ch = file->buf_ptr[0]; -+ next_tok_flags |= TOK_FLAG_BOW | TOK_FLAG_BOF | TOK_FLAG_BOL; -+ fch = file->buf_ptr[0]; - goto the_end; - } - break; -@@ -2945,104 +2091,104 @@ - c = 1; - goto do_ifdef; - case TOK_IF: -- c = expr_preprocess(); -+ c = expr_preprocess(st); - goto do_if; - case TOK_IFDEF: - c = 0; - do_ifdef: -- next_nomacro(); -+ next_nomacro(st); - if (tok < TOK_IDENT) -- error("invalid argument for '#if%sdef'", c ? "n" : ""); -+ tcc_error(st,"invalid argument for '#if%sdef'", c ? "n" : ""); - if (is_bof) { - if (c) { - #ifdef INC_DEBUG -- printf("#ifndef %s\n", get_tok_str(tok, NULL)); -+ printf("#ifndef %s\n", get_tok_str(st, tok, NULL)); - #endif - file->ifndef_macro = tok; - } - } -- c = (define_find(tok) != 0) ^ c; -+ c = (define_find(st, tok) != 0) ^ c; - do_if: -- if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) -- error("memory full"); -- *s1->ifdef_stack_ptr++ = c; -+ if (st->ifdef_stack_ptr >= st->ifdef_stack + IFDEF_STACK_SIZE) -+ tcc_error(st, "memory full"); -+ *st->ifdef_stack_ptr++ = c; - goto test_skip; - case TOK_ELSE: -- if (s1->ifdef_stack_ptr == s1->ifdef_stack) -- error("#else without matching #if"); -- if (s1->ifdef_stack_ptr[-1] & 2) -- error("#else after #else"); -- c = (s1->ifdef_stack_ptr[-1] ^= 3); -+ if (st->ifdef_stack_ptr == st->ifdef_stack) -+ tcc_error(st, "#else without matching #if"); -+ if (st->ifdef_stack_ptr[-1] & 2) -+ tcc_error(st, "#else after #else"); -+ c = (st->ifdef_stack_ptr[-1] ^= 3); - goto test_skip; - case TOK_ELIF: -- if (s1->ifdef_stack_ptr == s1->ifdef_stack) -- error("#elif without matching #if"); -- c = s1->ifdef_stack_ptr[-1]; -+ if (st->ifdef_stack_ptr == st->ifdef_stack) -+ tcc_error(st, "#elif without matching #if"); -+ c = st->ifdef_stack_ptr[-1]; - if (c > 1) -- error("#elif after #else"); -+ tcc_error(st, "#elif after #else"); - /* last #if/#elif expression was true: we skip */ - if (c == 1) - goto skip; -- c = expr_preprocess(); -- s1->ifdef_stack_ptr[-1] = c; -+ c = expr_preprocess(st); -+ st->ifdef_stack_ptr[-1] = c; - test_skip: - if (!(c & 1)) { - skip: -- preprocess_skip(); -+ preprocess_skip(st); - is_bof = 0; - goto redo; - } - break; - case TOK_ENDIF: -- if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr) -- error("#endif without matching #if"); -- s1->ifdef_stack_ptr--; -+ if (st->ifdef_stack_ptr <= file->ifdef_stack_ptr) -+ tcc_error(st, "#endif without matching #if"); -+ st->ifdef_stack_ptr--; - /* '#ifndef macro' was at the start of file. Now we check if - an '#endif' is exactly at the end of file */ - if (file->ifndef_macro && -- s1->ifdef_stack_ptr == file->ifdef_stack_ptr) { -+ st->ifdef_stack_ptr == file->ifdef_stack_ptr) { - file->ifndef_macro_saved = file->ifndef_macro; - /* need to set to zero to avoid false matches if another - #ifndef at middle of file */ - file->ifndef_macro = 0; - while (tok != TOK_LINEFEED) -- next_nomacro(); -- tok_flags |= TOK_FLAG_ENDIF; -+ next_nomacro(st); -+ next_tok_flags |= TOK_FLAG_ENDIF; - goto the_end; - } - break; - case TOK_LINE: -- next(); -+ next(st); - if (tok != TOK_CINT) -- error("#line"); -+ tcc_error(st, "#line"); - file->line_num = tokc.i - 1; /* the line number will be incremented after */ -- next(); -+ next(st); - if (tok != TOK_LINEFEED) { - if (tok != TOK_STR) -- error("#line"); -- pstrcpy(file->filename, sizeof(file->filename), -+ tcc_error(st, "#line"); -+ pstrcpy(st, file->filename, sizeof(file->filename), - (char *)tokc.cstr->data); - } - break; - case TOK_ERROR: - case TOK_WARNING: - c = tok; -- ch = file->buf_ptr[0]; -- skip_spaces(); -+ fch = file->buf_ptr[0]; -+ skip_spaces(st); - q = buf; -- while (ch != '\n' && ch != CH_EOF) { -+ while (fch != '\n' && fch != CH_EOF) { - if ((q - buf) < sizeof(buf) - 1) -- *q++ = ch; -- minp(); -+ *q++ = fch; -+ minp(st); - } - *q = '\0'; - if (c == TOK_ERROR) -- error("#error %s", buf); -+ tcc_error(st, "#error %s", buf); - else -- warning("#warning %s", buf); -+ warning(st, "#warning %s", buf); - break; - case TOK_PRAGMA: -- pragma_parse(s1); -+ pragma_parse(st); - break; - default: - if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { -@@ -3050,19 +2196,19 @@ - to emulate cpp behaviour */ - } else { - if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS)) -- error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc)); -+ tcc_error(st, "invalid preprocessing directive #%s", get_tok_str(st,tok, &tokc)); - } - break; - } - /* ignore other preprocess commands or #! for C scripts */ - while (tok != TOK_LINEFEED) -- next_nomacro(); -+ next_nomacro(st); - the_end: - parse_flags = saved_parse_flags; - } - - /* evaluate escape codes in a string. */ --static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long) -+static void parse_escape_string(TCCState *st, CString *outstr, const uint8_t *buf, int is_long) - { - int c, n; - const uint8_t *p; -@@ -3083,11 +2229,11 @@ - n = c - '0'; - p++; - c = *p; -- if (isoct(c)) { -+ if (isoct(st, c)) { - n = n * 8 + c - '0'; - p++; - c = *p; -- if (isoct(c)) { -+ if (isoct(st, c)) { - n = n * 8 + c - '0'; - p++; - } -@@ -3095,6 +2241,8 @@ - c = n; - goto add_char_nonext; - case 'x': -+ case 'u': -+ case 'U': - p++; - n = 0; - for(;;) { -@@ -3103,7 +2251,7 @@ - c = c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - c = c - 'A' + 10; -- else if (isnum(c)) -+ else if (isnum(st, c)) - c = c - '0'; - else - break; -@@ -3146,24 +2294,24 @@ - default: - invalid_escape: - if (c >= '!' && c <= '~') -- warning("unknown escape sequence: \'\\%c\'", c); -+ warning(st, "unknown escape sequence: \'\\%c\'", c); - else -- warning("unknown escape sequence: \'\\x%x\'", c); -+ warning(st, "unknown escape sequence: \'\\x%x\'", c); - break; - } - } - p++; - add_char_nonext: - if (!is_long) -- cstr_ccat(outstr, c); -+ cstr_ccat(st, outstr, c); - else -- cstr_wccat(outstr, c); -+ cstr_wccat(st, outstr, c); - } - /* add a trailing '\0' */ - if (!is_long) -- cstr_ccat(outstr, '\0'); -+ cstr_ccat(st, outstr, '\0'); - else -- cstr_wccat(outstr, '\0'); -+ cstr_wccat(st, outstr, '\0'); - } - - /* we use 64 bit numbers */ -@@ -3191,7 +2339,7 @@ - - /* parse number in null terminated string 'p' and return it in the - current token */ --void parse_number(const char *p) -+void parse_number(TCCState *st, const char *p) - { - int b, t, shift, frac_bits, s, exp_val, ch; - char *q; -@@ -3225,7 +2373,7 @@ - t = ch - 'a' + 10; - else if (ch >= 'A' && ch <= 'F') - t = ch - 'A' + 10; -- else if (isnum(ch)) -+ else if (isnum(st, ch)) - t = ch - '0'; - else - break; -@@ -3233,7 +2381,7 @@ - break; - if (q >= token_buf + STRING_MAX_SIZE) { - num_too_long: -- error("number too long"); -+ tcc_error(st, "number too long"); - } - *q++ = ch; - ch = *p++; -@@ -3282,14 +2430,14 @@ - break; - } - if (t >= b) -- error("invalid digit"); -+ tcc_error(st, "invalid digit"); - bn_lshift(bn, shift, t); - frac_bits += shift; - ch = *p++; - } - } - if (ch != 'p' && ch != 'P') -- expect("exponent"); -+ expect(st, "exponent"); - ch = *p++; - s = 1; - exp_val = 0; -@@ -3300,7 +2448,7 @@ - ch = *p++; - } - if (ch < '0' || ch > '9') -- expect("exponent digits"); -+ expect(st, "exponent digits"); - while (ch >= '0' && ch <= '9') { - exp_val = exp_val * 10 + ch - '0'; - ch = *p++; -@@ -3311,7 +2459,7 @@ - /* XXX: should patch directly float number */ - d = (double)bn[1] * 4294967296.0 + (double)bn[0]; - d = ldexp(d, exp_val - frac_bits); -- t = toup(ch); -+ t = toup(st, ch); - if (t == 'F') { - ch = *p++; - tok = TOK_CFLOAT; -@@ -3353,7 +2501,7 @@ - ch = *p++; - } - if (ch < '0' || ch > '9') -- expect("exponent digits"); -+ expect(st, "exponent digits"); - while (ch >= '0' && ch <= '9') { - if (q >= token_buf + STRING_MAX_SIZE) - goto num_too_long; -@@ -3362,7 +2510,7 @@ - } - } - *q = '\0'; -- t = toup(ch); -+ t = toup(st, ch); - errno = 0; - if (t == 'F') { - ch = *p++; -@@ -3401,14 +2549,14 @@ - } else { - t = t - '0'; - if (t >= b) -- error("invalid digit"); -+ tcc_error(st, "invalid digit"); - } - n1 = n; - n = n * b + t; - /* detect overflow */ - /* XXX: this test is not reliable */ - if (n < n1) -- error("integer constant overflow"); -+ tcc_error(st, "integer constant overflow"); - } - - /* XXX: not exactly ANSI compliant */ -@@ -3425,10 +2573,10 @@ - lcount = 0; - ucount = 0; - for(;;) { -- t = toup(ch); -+ t = toup(st, ch); - if (t == 'L') { - if (lcount >= 2) -- error("three 'l's in integer constant"); -+ tcc_error(st, "three 'l's in integer constant"); - lcount++; - if (lcount == 2) { - if (tok == TOK_CINT) -@@ -3439,7 +2587,7 @@ - ch = *p++; - } else if (t == 'U') { - if (ucount >= 1) -- error("two 'u's in integer constant"); -+ tcc_error(st, "two 'u's in integer constant"); - ucount++; - if (tok == TOK_CINT) - tok = TOK_CUINT; -@@ -3458,9 +2606,9 @@ - } - - --#define PARSE2(c1, tok1, c2, tok2) \ -+#define PARSE2(st, c1, tok1, c2, tok2) \ - case c1: \ -- PEEKC(c, p); \ -+ PEEKC(st, c, p); \ - if (c == c2) { \ - p++; \ - tok = tok2; \ -@@ -3470,7 +2618,7 @@ - break; - - /* return next token without macro substitution */ --static inline void next_nomacro1(void) -+static inline void next_nomacro1(TCCState *st) - { - int t, c, is_long; - TokenSym *ts; -@@ -3487,13 +2635,14 @@ - case '\v': - case '\r': - p++; -+ next_tok_flags |= TOK_FLAG_BOW; - goto redo_no_start; - - case '\\': - /* first look if it is in fact an end of buffer */ - if (p >= file->buf_end) { - file->buf_ptr = p; -- handle_eob(); -+ handle_eob(st); - p = file->buf_ptr; - if (p >= file->buf_end) - goto parse_eof; -@@ -3501,17 +2650,16 @@ - goto redo_no_start; - } else { - file->buf_ptr = p; -- ch = *p; -- handle_stray(); -+ fch = *p; -+ handle_stray(st); - p = file->buf_ptr; - goto redo_no_start; - } - parse_eof: - { -- TCCState *s1 = tcc_state; - if (parse_flags & PARSE_FLAG_LINEFEED) { - tok = TOK_LINEFEED; -- } else if (s1->include_stack_ptr == s1->include_stack || -+ } else if (st->include_stack_ptr == st->include_stack || - !(parse_flags & PARSE_FLAG_PREPROCESS)) { - /* no include left : end of file. */ - tok = TOK_EOF; -@@ -3520,22 +2668,22 @@ - - /* test if previous '#endif' was after a #ifdef at - start of file */ -- if (tok_flags & TOK_FLAG_ENDIF) { -+ if (next_tok_flags & TOK_FLAG_ENDIF) { - #ifdef INC_DEBUG -- printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); -+ printf("#endif %s\n", get_tok_str(st, file->ifndef_macro_saved, NULL)); - #endif -- add_cached_include(s1, file->inc_type, file->inc_filename, -+ add_cached_include(st, file->inc_type, file->inc_filename, - file->ifndef_macro_saved); - } - - /* add end of include file debug info */ - if (do_debug) { -- put_stabd(N_EINCL, 0, 0); -+ put_stabd(st, N_EINCL, 0, 0); - } - /* pop include stack */ - tcc_close(file); -- s1->include_stack_ptr--; -- file = *s1->include_stack_ptr; -+ st->include_stack_ptr--; -+ file = *st->include_stack_ptr; - p = file->buf_ptr; - goto redo_no_start; - } -@@ -3547,7 +2695,7 @@ - tok = TOK_LINEFEED; - } else { - file->line_num++; -- tok_flags |= TOK_FLAG_BOL; -+ next_tok_flags |= TOK_FLAG_BOW | TOK_FLAG_BOL; - p++; - goto redo_no_start; - } -@@ -3555,11 +2703,11 @@ - - case '#': - /* XXX: simplify */ -- PEEKC(c, p); -- if ((tok_flags & TOK_FLAG_BOL) && -+ PEEKC(st, c, p); -+ if ((next_tok_flags & TOK_FLAG_BOL) && - (parse_flags & PARSE_FLAG_PREPROCESS)) { - file->buf_ptr = p; -- preprocess(tok_flags & TOK_FLAG_BOF); -+ preprocess(st, next_tok_flags & TOK_FLAG_BOF); - p = file->buf_ptr; - goto redo_no_start; - } else { -@@ -3568,7 +2716,7 @@ - tok = TOK_TWOSHARPS; - } else { - if (parse_flags & PARSE_FLAG_ASM_COMMENTS) { -- p = parse_line_comment(p - 1); -+ p = parse_line_comment(st, p - 1); - goto redo_no_start; - } else { - tok = '#'; -@@ -3621,24 +2769,24 @@ - goto token_found; - pts = &(ts->hash_next); - } -- ts = tok_alloc_new(pts, p1, len); -+ ts = tok_alloc_new(st, pts, p1, len); - token_found: ; - } else { - /* slower case */ -- cstr_reset(&tokcstr); -+ cstr_reset(st, &tokcstr); - - while (p1 < p) { -- cstr_ccat(&tokcstr, *p1); -+ cstr_ccat(st, &tokcstr, *p1); - p1++; - } - p--; -- PEEKC(c, p); -+ PEEKC(st, c, p); - parse_ident_slow: - while (isidnum_table[c]) { -- cstr_ccat(&tokcstr, c); -- PEEKC(c, p); -+ cstr_ccat(st, &tokcstr, c); -+ PEEKC(st, c, p); - } -- ts = tok_alloc(tokcstr.data, tokcstr.size); -+ ts = tok_alloc(st, tokcstr.data, tokcstr.size); - } - tok = ts->tok; - break; -@@ -3648,13 +2796,13 @@ - /* fast case */ - goto parse_ident_fast; - } else { -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '\'' || c == '\"') { - is_long = 1; - goto str_const; - } else { -- cstr_reset(&tokcstr); -- cstr_ccat(&tokcstr, 'L'); -+ cstr_reset(st, &tokcstr); -+ cstr_ccat(st, &tokcstr, 'L'); - goto parse_ident_slow; - } - } -@@ -3663,36 +2811,36 @@ - case '4': case '5': case '6': case '7': - case '8': case '9': - -- cstr_reset(&tokcstr); -+ cstr_reset(st, &tokcstr); - /* after the first digit, accept digits, alpha, '.' or sign if - prefixed by 'eEpP' */ - parse_num: - for(;;) { - t = c; -- cstr_ccat(&tokcstr, c); -- PEEKC(c, p); -- if (!(isnum(c) || isid(c) || c == '.' || -+ cstr_ccat(st, &tokcstr, c); -+ PEEKC(st, c, p); -+ if (!(isnum(st, c) || isid(st, c) || c == '.' || - ((c == '+' || c == '-') && - (t == 'e' || t == 'E' || t == 'p' || t == 'P')))) - break; - } - /* We add a trailing '\0' to ease parsing */ -- cstr_ccat(&tokcstr, '\0'); -+ cstr_ccat(st, &tokcstr, '\0'); - tokc.cstr = &tokcstr; - tok = TOK_PPNUM; - break; - case '.': - /* special dot handling because it can also start a number */ -- PEEKC(c, p); -- if (isnum(c)) { -- cstr_reset(&tokcstr); -- cstr_ccat(&tokcstr, '.'); -+ PEEKC(st, c, p); -+ if (isnum(st, c)) { -+ cstr_reset(st, &tokcstr); -+ cstr_ccat(st, &tokcstr, '.'); - goto parse_num; - } else if (c == '.') { -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c != '.') -- expect("'.'"); -- PEEKC(c, p); -+ expect(st, "'.'"); -+ PEEKC(st, c, p); - tok = TOK_DOTS; - } else { - tok = '.'; -@@ -3709,14 +2857,14 @@ - sep = c; - - /* parse the string */ -- cstr_new(&str); -- p = parse_pp_string(p, sep, &str); -- cstr_ccat(&str, '\0'); -+ cstr_new(st, &str); -+ p = parse_pp_string(st, p, sep, &str); -+ cstr_ccat(st, &str, '\0'); - - /* eval the escape (should be done as TOK_PPNUM) */ -- cstr_reset(&tokcstr); -- parse_escape_string(&tokcstr, str.data, is_long); -- cstr_free(&str); -+ cstr_reset(st, &tokcstr); -+ parse_escape_string(st, &tokcstr, str.data, is_long); -+ cstr_free(st, &str); - - if (sep == '\'') { - int char_size; -@@ -3724,16 +2872,16 @@ - if (!is_long) - char_size = 1; - else -- char_size = sizeof(int); -+ char_size = sizeof(nwchar_t); - if (tokcstr.size <= char_size) -- error("empty character constant"); -+ tcc_error(st, "empty character constant"); - if (tokcstr.size > 2 * char_size) -- warning("multi-character character constant"); -+ warning(st, "multi-character character constant"); - if (!is_long) { - tokc.i = *(int8_t *)tokcstr.data; - tok = TOK_CCHAR; - } else { -- tokc.i = *(int *)tokcstr.data; -+ tokc.i = *(nwchar_t *)tokcstr.data; - tok = TOK_LCHAR; - } - } else { -@@ -3747,12 +2895,12 @@ - break; - - case '<': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '=') { - p++; - tok = TOK_LE; - } else if (c == '<') { -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '=') { - p++; - tok = TOK_A_SHL; -@@ -3765,12 +2913,12 @@ - break; - - case '>': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '=') { - p++; - tok = TOK_GE; - } else if (c == '>') { -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '=') { - p++; - tok = TOK_A_SAR; -@@ -3783,7 +2931,7 @@ - break; - - case '&': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '&') { - p++; - tok = TOK_LAND; -@@ -3796,7 +2944,7 @@ - break; - - case '|': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '|') { - p++; - tok = TOK_LOR; -@@ -3809,7 +2957,7 @@ - break; - - case '+': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '+') { - p++; - tok = TOK_INC; -@@ -3822,7 +2970,7 @@ - break; - - case '-': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '-') { - p++; - tok = TOK_DEC; -@@ -3837,20 +2985,22 @@ - } - break; - -- PARSE2('!', '!', '=', TOK_NE) -- PARSE2('=', '=', '=', TOK_EQ) -- PARSE2('*', '*', '=', TOK_A_MUL) -- PARSE2('%', '%', '=', TOK_A_MOD) -- PARSE2('^', '^', '=', TOK_A_XOR) -+ PARSE2(st, '!', '!', '=', TOK_NE) -+ PARSE2(st, '=', '=', '=', TOK_EQ) -+ PARSE2(st, '*', '*', '=', TOK_A_MUL) -+ PARSE2(st, '%', '%', '=', TOK_A_MOD) -+ PARSE2(st, '^', '^', '=', TOK_A_XOR) - - /* comments or operator */ - case '/': -- PEEKC(c, p); -+ PEEKC(st, c, p); - if (c == '*') { -- p = parse_comment(p); -+ p = parse_comment(st, p); -+ next_tok_flags |= TOK_FLAG_BOW; - goto redo_no_start; - } else if (c == '/') { -- p = parse_line_comment(p); -+ p = parse_line_comment(st, p); -+ next_tok_flags |= TOK_FLAG_BOW; - goto redo_no_start; - } else if (c == '=') { - p++; -@@ -3878,82 +3028,85 @@ - p++; - break; - default: -- error("unrecognized character \\x%02x", c); -+ tcc_error(st, "unrecognized character \\x%02x", c); - break; - } - file->buf_ptr = p; -- tok_flags = 0; -+ tok_flags = next_tok_flags; -+ next_tok_flags = 0; - #if defined(PARSE_DEBUG) -- printf("token = %s\n", get_tok_str(tok, &tokc)); -+ printf("token = %s\n", get_tok_str(st, tok, &tokc)); - #endif - } - - /* return next token without macro substitution. Can read input from - macro_ptr buffer */ --static void next_nomacro(void) -+static void next_nomacro(TCCState *st) - { - if (macro_ptr) { - redo: - tok = *macro_ptr; - if (tok) { -- TOK_GET(tok, macro_ptr, tokc); -+ TOK_GET(tok, tok_flags, macro_ptr, tokc); - if (tok == TOK_LINENUM) { - file->line_num = tokc.i; - goto redo; - } - } - } else { -- next_nomacro1(); -+ next_nomacro1(st ); - } - } - - /* substitute args in macro_str and return allocated string */ --static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) -+static int *macro_arg_subst(TCCState *state, Sym **nested_list, int *macro_str, Sym *args) - { -- int *st, last_tok, t, notfirst; -+ int *st, last_tok, t, tf, save_tf, notfirst; - Sym *s; - CValue cval; - TokenString str; - CString cstr; - -- tok_str_new(&str); -+ tok_str_new(state, &str); - last_tok = 0; - while(1) { -- TOK_GET(t, macro_str, cval); -+ TOK_GET(t, tf, macro_str, cval); -+ save_tf = tf; - if (!t) - break; - if (t == '#') { - /* stringize */ -- TOK_GET(t, macro_str, cval); -+ TOK_GET(t, tf, macro_str, cval); - if (!t) - break; -- s = sym_find2(args, t); -+ s = sym_find2(state, args, t); - if (s) { -- cstr_new(&cstr); -+ cstr_new(state, &cstr); - st = (int *)s->c; - notfirst = 0; - while (*st) { -- if (notfirst) -- cstr_ccat(&cstr, ' '); -- TOK_GET(t, st, cval); -- cstr_cat(&cstr, get_tok_str(t, &cval)); -+ TOK_GET(t, tf, st, cval); -+ if (notfirst && tf & TOK_FLAG_BOW) -+ cstr_ccat(state, &cstr, ' '); -+ cstr_cat(state, &cstr, get_tok_str(state, t, &cval)); - notfirst = 1; - } -- cstr_ccat(&cstr, '\0'); -+ cstr_ccat(state, &cstr, '\0'); - #ifdef PP_DEBUG - printf("stringize: %s\n", (char *)cstr.data); - #endif - /* add string */ - cval.cstr = &cstr; -- tok_str_add2(&str, TOK_STR, &cval); -- cstr_free(&cstr); -+ tok_str_add2(state, &str, TOK_STR, save_tf, &cval); -+ cstr_free(state, &cstr); - } else { -- tok_str_add2(&str, t, &cval); -+ tok_str_add2(state, &str, t, save_tf, &cval); - } - } else if (t >= TOK_IDENT) { -- s = sym_find2(args, t); -+ s = sym_find2(state, args, t); - if (s) { - st = (int *)s->c; -+ st[1] = save_tf; - /* if '##' is present before or after, no arg substitution */ - if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) { - /* special case for var arg macros : ## eats the -@@ -3963,39 +3116,40 @@ - problems */ - if (gnu_ext && s->type.t && - last_tok == TOK_TWOSHARPS && -- str.len >= 2 && str.str[str.len - 2] == ',') { -+ str.len >= 4 && str.str[str.len - 4] == ',') { - if (*st == 0) { - /* suppress ',' '##' */ -- str.len -= 2; -+ str.len -= 4; -+ next_tok_flags = tok_flags; - } else { - /* suppress '##' and add variable */ -- str.len--; -+ str.len -= 2; - goto add_var; - } - } else { - int t1; - add_var: - for(;;) { -- TOK_GET(t1, st, cval); -+ TOK_GET(t1, tf, st, cval); - if (!t1) - break; -- tok_str_add2(&str, t1, &cval); -+ tok_str_add2(state, &str, t1, save_tf, &cval); - } - } - } else { - /* NOTE: the stream cannot be read when macro - substituing an argument */ -- macro_subst(&str, nested_list, st, NULL); -+ macro_subst(state, &str, nested_list, st, NULL); - } - } else { -- tok_str_add(&str, t); -+ tok_str_add(state, &str, t, tf); - } - } else { -- tok_str_add2(&str, t, &cval); -+ tok_str_add2(state, &str, t, tf, &cval); - } - last_tok = t; - } -- tok_str_add(&str, 0); -+ tok_str_add(state, &str, 0, 0); - return str.str; - } - -@@ -4009,7 +3163,7 @@ - result to (tok_str,tok_len). 'nested_list' is the list of all - macros we got inside to avoid recursing. Return non zero if no - substitution needs to be done */ --static int macro_subst_tok(TokenString *tok_str, -+static int macro_subst_tok(TCCState *st, TokenString *tok_str, - Sym **nested_list, Sym *s, struct macro_level **can_read_stream) - { - Sym *args, *sa, *sa1; -@@ -4047,14 +3201,15 @@ - add_cstr: - t1 = TOK_STR; - add_cstr1: -- cstr_new(&cstr); -- cstr_cat(&cstr, cstrval); -- cstr_ccat(&cstr, '\0'); -+ cstr_new(st, &cstr); -+ cstr_cat(st, &cstr, cstrval); -+ cstr_ccat(st, &cstr, '\0'); - cval.cstr = &cstr; -- tok_str_add2(tok_str, t1, &cval); -- cstr_free(&cstr); -+ tok_str_add2(st, tok_str, t1, tok_flags, &cval); -+ cstr_free(st, &cstr); - } else { - mstr = (int *)s->c; -+ mstr[1] = tok_flags; - mstr_allocated = 0; - if (s->type.t == MACRO_FUNC) { - /* NOTE: we do not use next_nomacro to avoid eating the -@@ -4077,17 +3232,17 @@ - } - } else { - /* XXX: incorrect with comments */ -- ch = file->buf_ptr[0]; -- while (is_space(ch) || ch == '\n') -- cinp(); -- t = ch; -+ fch = file->buf_ptr[0]; -+ while (is_space(st, fch) || fch == '\n') -+ cinp(st); -+ t = fch; - } - if (t != '(') /* no macro subst */ - return -1; - - /* argument macro */ -- next_nomacro(); -- next_nomacro(); -+ next_nomacro(st); -+ next_nomacro(st); - args = NULL; - sa = s->next; - /* NOTE: empty args are allowed, except if no args */ -@@ -4096,9 +3251,9 @@ - if (!args && !sa && tok == ')') - break; - if (!sa) -- error("macro '%s' used with too many args", -- get_tok_str(s->v, 0)); -- tok_str_new(&str); -+ tcc_error(st, "macro '%s' used with too many args", -+ get_tok_str(st, s->v, 0)); -+ tok_str_new(st, &str); - parlevel = 0; - /* NOTE: non zero sa->t indicates VA_ARGS */ - while ((parlevel > 0 || -@@ -4109,11 +3264,11 @@ - parlevel++; - else if (tok == ')') - parlevel--; -- tok_str_add2(&str, tok, &tokc); -- next_nomacro(); -+ tok_str_add2(st, &str, tok, tok_flags, &tokc); -+ next_nomacro(st); - } -- tok_str_add(&str, 0); -- sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str); -+ tok_str_add(st, &str, 0, 0); -+ sym_push2(st, &args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str); - sa = sa->next; - if (tok == ')') { - /* special case for gcc var args: add an empty -@@ -4124,45 +3279,45 @@ - break; - } - if (tok != ',') -- expect(","); -- next_nomacro(); -+ expect(st, ","); -+ next_nomacro(st); - } - if (sa) { -- error("macro '%s' used with too few args", -- get_tok_str(s->v, 0)); -+ tcc_error(st, "macro '%s' used with too few args", -+ get_tok_str(st, s->v, 0)); - } - - /* now subst each arg */ -- mstr = macro_arg_subst(nested_list, mstr, args); -+ mstr = macro_arg_subst(st, nested_list, mstr, args); - /* free memory */ - sa = args; - while (sa) { - sa1 = sa->prev; -- tok_str_free((int *)sa->c); -- sym_free(sa); -+ tok_str_free(st, (int *)sa->c); -+ sym_free(st, sa); - sa = sa1; - } - mstr_allocated = 1; - } -- sym_push2(nested_list, s->v, 0, 0); -- macro_subst(tok_str, nested_list, mstr, can_read_stream); -+ sym_push2(st, nested_list, s->v, 0, 0); -+ macro_subst(st, tok_str, nested_list, mstr, can_read_stream); - /* pop nested defined symbol */ - sa1 = *nested_list; - *nested_list = sa1->prev; -- sym_free(sa1); -+ sym_free(st, sa1); - if (mstr_allocated) -- tok_str_free(mstr); -+ tok_str_free(st, mstr); - } - return 0; - } - - /* handle the '##' operator. Return NULL if no '##' seen. Otherwise - return the resulting string (which must be freed). */ --static inline int *macro_twosharps(const int *macro_str) -+static inline int *macro_twosharps(TCCState *st, const int *macro_str) - { - TokenSym *ts; - const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr; -- int t; -+ int t, tf; - const char *p1, *p2; - CValue cval; - TokenString macro_str1; -@@ -4172,7 +3327,7 @@ - /* we search the first '##' */ - for(;;) { - macro_ptr1 = macro_str; -- TOK_GET(t, macro_str, cval); -+ TOK_GET(t, tf, macro_str, cval); - /* nothing more to do if end of string */ - if (t == 0) - return NULL; -@@ -4181,42 +3336,48 @@ - } - - /* we saw '##', so we need more processing to handle it */ -- cstr_new(&cstr); -- tok_str_new(¯o_str1); -+ cstr_new(st, &cstr); -+ tok_str_new(st, ¯o_str1); - tok = t; -+ tok_flags = tf; - tokc = cval; - - /* add all tokens seen so far */ - for(ptr = start_macro_ptr; ptr < macro_ptr1;) { -- TOK_GET(t, ptr, cval); -- tok_str_add2(¯o_str1, t, &cval); -+ TOK_GET(t, tf, ptr, cval); -+ tok_str_add2(st, ¯o_str1, t, tf, &cval); - } - saved_macro_ptr = macro_ptr; - /* XXX: get rid of the use of macro_ptr here */ - macro_ptr = (int *)macro_str; - for(;;) { - while (*macro_ptr == TOK_TWOSHARPS) { -- macro_ptr++; -+ macro_ptr+=2; - macro_ptr1 = macro_ptr; - t = *macro_ptr; - if (t) { -- TOK_GET(t, macro_ptr, cval); -+ TOK_GET(t, tf, macro_ptr, cval); - /* We concatenate the two tokens if we have an - identifier or a preprocessing number */ -- cstr_reset(&cstr); -- p1 = get_tok_str(tok, &tokc); -- cstr_cat(&cstr, p1); -- p2 = get_tok_str(t, &cval); -- cstr_cat(&cstr, p2); -- cstr_ccat(&cstr, '\0'); -+ cstr_reset(st, &cstr); -+ p1 = get_tok_str(st, tok, &tokc); -+ cstr_cat(st, &cstr, p1); -+ p2 = get_tok_str(st, t, &cval); -+ cstr_cat(st, &cstr, p2); -+ cstr_ccat(st, &cstr, '\0'); - - if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && - (t >= TOK_IDENT || t == TOK_PPNUM)) { - if (tok == TOK_PPNUM) { - /* if number, then create a number token */ -- /* NOTE: no need to allocate because -- tok_str_add2() does it */ -- tokc.cstr = &cstr; -+ /* NOTE: we cannot use cstr directly for this -+ because if there are multiple token pastings -+ in a sequence the concatenation will reset -+ cstr before the final token is ready. */ -+ cstr_reset(st, &tokcstr); -+ cstr_cat(st, &tokcstr, cstr.data); -+ cstr_ccat(st, &tokcstr, '\0'); -+ tokc.cstr = &tokcstr; - } else { - /* if identifier, we must do a test to - validate we have a correct identifier */ -@@ -4230,11 +3391,11 @@ - if (c == '\0') - break; - p++; -- if (!isnum(c) && !isid(c)) -+ if (!isnum(st, c) && !isid(st, c)) - goto error_pasting; - } - } -- ts = tok_alloc(cstr.data, strlen(cstr.data)); -+ ts = tok_alloc(st, cstr.data, strlen(cstr.data)); - tok = ts->tok; /* modify current token */ - } - } else { -@@ -4262,14 +3423,14 @@ - error_pasting: - /* NOTE: because get_tok_str use a static buffer, - we must save it */ -- cstr_reset(&cstr); -- p1 = get_tok_str(tok, &tokc); -- cstr_cat(&cstr, p1); -- cstr_ccat(&cstr, '\0'); -- p2 = get_tok_str(t, &cval); -- warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); -+ cstr_reset(st, &cstr); -+ p1 = get_tok_str(st, tok, &tokc); -+ cstr_cat(st, &cstr, p1); -+ cstr_ccat(st, &cstr, '\0'); -+ p2 = get_tok_str(st, t, &cval); -+ warning(st, "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); - /* cannot merge tokens: just add them separately */ -- tok_str_add2(¯o_str1, tok, &tokc); -+ tok_str_add2(st, ¯o_str1, tok, tok_flags, &tokc); - /* XXX: free associated memory ? */ - tok = t; - tokc = cval; -@@ -4277,14 +3438,14 @@ - } - } - } -- tok_str_add2(¯o_str1, tok, &tokc); -- next_nomacro(); -+ tok_str_add2(st, ¯o_str1, tok, tok_flags, &tokc); -+ next_nomacro(st); - if (tok == 0) - break; - } - macro_ptr = (int *)saved_macro_ptr; -- cstr_free(&cstr); -- tok_str_add(¯o_str1, 0); -+ cstr_free(st, &cstr); -+ tok_str_add(st, ¯o_str1, 0, 0); - return macro_str1.str; - } - -@@ -4292,19 +3453,19 @@ - /* do macro substitution of macro_str and add result to - (tok_str,tok_len). 'nested_list' is the list of all macros we got - inside to avoid recursing. */ --static void macro_subst(TokenString *tok_str, Sym **nested_list, -+static void macro_subst(TCCState *st, TokenString *tok_str, Sym **nested_list, - const int *macro_str, struct macro_level ** can_read_stream) - { - Sym *s; - int *macro_str1; - const int *ptr; -- int t, ret; -+ int t, tf, ret; - CValue cval; - struct macro_level ml; - - /* first scan for '##' operator handling */ - ptr = macro_str; -- macro_str1 = macro_twosharps(ptr); -+ macro_str1 = macro_twosharps(st, ptr); - if (macro_str1) - ptr = macro_str1; - while (1) { -@@ -4312,20 +3473,21 @@ - file stream due to a macro function call */ - if (ptr == NULL) - break; -- TOK_GET(t, ptr, cval); -+ TOK_GET(t, tf, ptr, cval); - if (t == 0) - break; -- s = define_find(t); -+ s = define_find(st, t); - if (s != NULL) { - /* if nested substitution, do nothing */ -- if (sym_find2(*nested_list, t)) -+ if (sym_find2(st, *nested_list, t)) - goto no_subst; - ml.p = macro_ptr; - if (can_read_stream) - ml.prev = *can_read_stream, *can_read_stream = &ml; - macro_ptr = (int *)ptr; - tok = t; -- ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream); -+ tok_flags = tf; -+ ret = macro_subst_tok(st, tok_str, nested_list, s, can_read_stream); - ptr = (int *)macro_ptr; - macro_ptr = ml.p; - if (can_read_stream && *can_read_stream == &ml) -@@ -4334,36 +3496,37 @@ - goto no_subst; - } else { - no_subst: -- tok_str_add2(tok_str, t, &cval); -+ tok_str_add2(st, tok_str, t, tf, &cval); - } - } - if (macro_str1) -- tok_str_free(macro_str1); -+ tok_str_free(st, macro_str1); - } - -+ - /* return next token with macro substitution */ --static void next(void) -+static void next(TCCState *st) - { - Sym *nested_list, *s; - TokenString str; - struct macro_level *ml; - - redo: -- next_nomacro(); -+ next_nomacro(st); - if (!macro_ptr) { - /* if not reading from macro substituted string, then try - to substitute macros */ - if (tok >= TOK_IDENT && - (parse_flags & PARSE_FLAG_PREPROCESS)) { -- s = define_find(tok); -+ s = define_find(st, tok); - if (s) { - /* we have a macro: we try to substitute */ -- tok_str_new(&str); -+ tok_str_new(st, &str); - nested_list = NULL; - ml = NULL; -- if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) { -+ if (macro_subst_tok(st, &str, &nested_list, s, &ml) == 0) { - /* substitution done, NOTE: maybe empty */ -- tok_str_add(&str, 0); -+ tok_str_add(st, &str, 0, 0); - macro_ptr = str.str; - macro_ptr_allocated = str.str; - goto redo; -@@ -4378,7 +3541,7 @@ - unget_buffer_enabled = 0; - } else { - /* end of macro string: free it */ -- tok_str_free(macro_ptr_allocated); -+ tok_str_free(st, macro_ptr_allocated); - macro_ptr = NULL; - } - goto redo; -@@ -4388,13 +3551,14 @@ - /* convert preprocessor tokens into C tokens */ - if (tok == TOK_PPNUM && - (parse_flags & PARSE_FLAG_TOK_NUM)) { -- parse_number((char *)tokc.cstr->data); -+ parse_number(st, (char *)tokc.cstr->data); - } -+ - } - - /* push back current token and set current token to 'last_tok'. Only - identifier case handled for labels. */ --static inline void unget_tok(int last_tok) -+static inline void unget_tok(TCCState *st, int last_tok) - { - int i, n; - int *q; -@@ -4403,7 +3567,7 @@ - q = unget_saved_buffer; - macro_ptr = q; - *q++ = tok; -- n = tok_ext_size(tok) - 1; -+ n = tok_ext_size(st, tok) - 1; - for(i=0;i= vstack + (VSTACK_SIZE - 1)) -- error("memory full"); -+ tcc_error(st, "memory full"); - /* cannot let cpu flags if other instruction are generated. Also - avoid leaving VT_JMP anywhere except on the top of the stack - because it would complicate the code generator. */ - if (vtop >= vstack) { - v = vtop->r & VT_VALMASK; - if (v == VT_CMP || (v & ~1) == VT_JMP) -- gv(RC_INT); -+ gv(st, RC_INT); - } - vtop++; - vtop->type = *type; -@@ -4441,47 +3605,47 @@ - } - - /* push integer constant */ --void vpushi(int v) -+void vpushi(TCCState *st, int v) - { - CValue cval; - cval.i = v; -- vsetc(&int_type, VT_CONST, &cval); -+ vsetc(st, &int_type, VT_CONST, &cval); - } - - /* Return a static symbol pointing to a section */ --static Sym *get_sym_ref(CType *type, Section *sec, -+static Sym *get_sym_ref(TCCState *st, CType *type, Section *sec, - unsigned long offset, unsigned long size) - { - int v; - Sym *sym; - - v = anon_sym++; -- sym = global_identifier_push(v, type->t | VT_STATIC, 0); -+ sym = global_identifier_push(st, v, type->t | VT_STATIC, 0); - sym->type.ref = type->ref; - sym->r = VT_CONST | VT_SYM; -- put_extern_sym(sym, sec, offset, size); -+ put_extern_sym(st, sym, sec, offset, size); - return sym; - } - - /* push a reference to a section offset by adding a dummy symbol */ --static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) -+static void vpush_ref(TCCState *s, CType *type, Section *sec, unsigned long offset, unsigned long size) - { - CValue cval; - - cval.ul = 0; -- vsetc(type, VT_CONST | VT_SYM, &cval); -- vtop->sym = get_sym_ref(type, sec, offset, size); -+ vsetc(s, type, VT_CONST | VT_SYM, &cval); -+ vtop->sym = get_sym_ref(s, type, sec, offset, size); - } - - /* define a new external reference to a symbol 'v' of type 'u' */ --static Sym *external_global_sym(int v, CType *type, int r) -+static Sym *external_global_sym(TCCState * st, int v, CType *type, int r) - { - Sym *s; - -- s = sym_find(v); -+ s = sym_find(st, v); - if (!s) { - /* push forward reference */ -- s = global_identifier_push(v, type->t | VT_EXTERN, 0); -+ s = global_identifier_push(st, v, type->t | VT_EXTERN, 0); - s->type.ref = type->ref; - s->r = r | VT_CONST | VT_SYM; - } -@@ -4489,51 +3653,51 @@ - } - - /* define a new external reference to a symbol 'v' of type 'u' */ --static Sym *external_sym(int v, CType *type, int r) -+static Sym *external_sym(TCCState *st, int v, CType *type, int r) - { - Sym *s; - -- s = sym_find(v); -+ s = sym_find(st, v); - if (!s) { - /* push forward reference */ -- s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); -+ s = sym_push(st, v, type, r | VT_CONST | VT_SYM, 0); - s->type.t |= VT_EXTERN; - } else { -- if (!is_compatible_types(&s->type, type)) -- error("incompatible types for redefinition of '%s'", -- get_tok_str(v, NULL)); -+ if (!is_compatible_types(st, &s->type, type)) -+ tcc_error(st, "incompatible types for redefinition of '%s'", -+ get_tok_str(st, v, NULL)); - } - return s; - } - - /* push a reference to global symbol v */ --static void vpush_global_sym(CType *type, int v) -+static void vpush_global_sym(TCCState *st, CType *type, int v) - { - Sym *sym; - CValue cval; - -- sym = external_global_sym(v, type, 0); -+ sym = external_global_sym(st, v, type, 0); - cval.ul = 0; -- vsetc(type, VT_CONST | VT_SYM, &cval); -+ vsetc(st, type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; - } - --void vset(CType *type, int r, int v) -+void vset(TCCState *st, CType *type, int r, int v) - { - CValue cval; - - cval.i = v; -- vsetc(type, r, &cval); -+ vsetc(st, type, r, &cval); - } - --void vseti(int r, int v) -+void vseti(TCCState *st, int r, int v) - { - CType type; - type.t = VT_INT; -- vset(&type, r, v); -+ vset(st, &type, r, v); - } - --void vswap(void) -+void vswap(TCCState *st) - { - SValue tmp; - -@@ -4542,21 +3706,21 @@ - vtop[-1] = tmp; - } - --void vpushv(SValue *v) -+void vpushv(TCCState *st, SValue *v) - { - if (vtop >= vstack + (VSTACK_SIZE - 1)) -- error("memory full"); -+ tcc_error(st, "memory full"); - vtop++; - *vtop = *v; - } - --void vdup(void) -+void vdup(TCCState *st) - { -- vpushv(vtop); -+ vpushv(st, vtop); - } - - /* save r to the memory stack, and mark it as being free */ --void save_reg(int r) -+void save_reg(TCCState *st, int r) - { - int l, saved, size, align; - SValue *p, sv; -@@ -4567,7 +3731,8 @@ - l = 0; - for(p=vstack;p<=vtop;p++) { - if ((p->r & VT_VALMASK) == r || -- (p->r2 & VT_VALMASK) == r) { -+ ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) -+ { - /* must save value on stack if not already done */ - if (!saved) { - /* NOTE: must reload 'r' because r might be equal to r2 */ -@@ -4575,24 +3740,24 @@ - /* store register in the stack */ - type = &p->type; - if ((p->r & VT_LVAL) || -- (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG)) -+ (!is_float(st, type->t) && (type->t & VT_BTYPE) != VT_LLONG)) - type = &int_type; -- size = type_size(type, &align); -+ size = type_size(st, type, &align); - loc = (loc - size) & -align; - sv.type.t = type->t; - sv.r = VT_LOCAL | VT_LVAL; - sv.c.ul = loc; -- store(r, &sv); -+ store(st, r, &sv); - #ifdef TCC_TARGET_I386 - /* x86 specific: need to pop fp register ST0 if saved */ - if (r == TREG_ST0) { -- o(0xd9dd); /* fstp %st(1) */ -+ o(st, 0xd9dd); /* fstp %st(1) */ - } - #endif - /* special long long case */ - if ((type->t & VT_BTYPE) == VT_LLONG) { - sv.c.ul += 4; -- store(p->r2, &sv); -+ store(st, p->r2, &sv); - } - l = loc; - saved = 1; -@@ -4604,7 +3769,7 @@ - p->c.ul */ - p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL; - } else { -- p->r = lvalue_type(p->type.t) | VT_LOCAL; -+ p->r = lvalue_type(st, p->type.t) | VT_LOCAL; - } - p->r2 = VT_CONST; - p->c.ul = l; -@@ -4614,7 +3779,7 @@ - - /* find a register of class 'rc2' with at most one reference on stack. - * If none, call get_reg(rc) */ --int get_reg_ex(int rc, int rc2) -+int get_reg_ex(TCCState *st, int rc, int rc2) - { - int r; - SValue *p; -@@ -4632,11 +3797,11 @@ - return r; - } - } -- return get_reg(rc); -+ return get_reg(st, rc); - } - - /* find a free register of class 'rc'. If none, save one register */ --int get_reg(int rc) -+int get_reg(TCCState *st, int rc) - { - int r; - SValue *p; -@@ -4665,7 +3830,7 @@ - r = p->r2 & VT_VALMASK; - if (r < VT_CONST && (reg_classes[r] & rc)) { - save_found: -- save_reg(r); -+ save_reg(st, r); - return r; - } - } -@@ -4674,7 +3839,7 @@ - } - - /* save registers up to (vtop - n) stack entry */ --void save_regs(int n) -+void save_regs(TCCState *st, int n) - { - int r; - SValue *p, *p1; -@@ -4682,28 +3847,28 @@ - for(p = vstack;p <= p1; p++) { - r = p->r & VT_VALMASK; - if (r < VT_CONST) { -- save_reg(r); -+ save_reg(st, r); - } - } - } - - /* move register 's' to 'r', and flush previous value of r to memory - if needed */ --void move_reg(int r, int s) -+void move_reg(TCCState *st, int r, int s) - { - SValue sv; - - if (r != s) { -- save_reg(r); -+ save_reg(st, r); - sv.type.t = VT_INT; - sv.r = s; - sv.c.ul = 0; -- load(r, &sv); -+ load(st, r, &sv); - } - } - - /* get address of vtop (vtop MUST BE an lvalue) */ --void gaddrof(void) -+void gaddrof(TCCState *st) - { - vtop->r &= ~VT_LVAL; - /* tricky: if saved lvalue, then we can go back to lvalue */ -@@ -4711,9 +3876,9 @@ - vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL; - } - --#ifdef CONFIG_TCC_BCHECK -+#if 0 - /* generate lvalue bound code */ --void gbound(void) -+void gbound(TCCState *st) - { - int lval_type; - CType type1; -@@ -4727,14 +3892,14 @@ - /* must save type because we must set it to int to get pointer */ - type1 = vtop->type; - vtop->type.t = VT_INT; -- gaddrof(); -- vpushi(0); -- gen_bounded_ptr_add(); -+ gaddrof(st ); -+ vpushi(st, 0); -+ gen_bounded_ptr_add(st); - vtop->r |= lval_type; - vtop->type = type1; - } - /* then check for dereferencing */ -- gen_bounded_ptr_deref(); -+ gen_bounded_ptr_deref(st); - } - } - #endif -@@ -4742,7 +3907,7 @@ - /* store vtop a register belonging to class 'rc'. lvalues are - converted to values. Cannot be used if cannot be converted to - register value (such as structures). */ --int gv(int rc) -+int gv(TCCState *st, int rc) - { - int r, r2, rc2, bit_pos, bit_size, size, align, i; - unsigned long long ll; -@@ -4754,38 +3919,55 @@ - /* remove bit field info to avoid loops */ - vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - /* generate shifts */ -- vpushi(32 - (bit_pos + bit_size)); -- gen_op(TOK_SHL); -- vpushi(32 - bit_size); -+ vpushi(st, 32 - (bit_pos + bit_size)); -+ gen_op(st, TOK_SHL); -+ vpushi(st, 32 - bit_size); - /* NOTE: transformed to SHR if unsigned */ -- gen_op(TOK_SAR); -- r = gv(rc); -+ gen_op(st, TOK_SAR); -+ r = gv(st, rc); - } else { -- if (is_float(vtop->type.t) && -+ if (is_float(st, vtop->type.t) && - (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - Sym *sym; - int *ptr; - unsigned long offset; -+#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) -+ CValue check; -+#endif - - /* XXX: unify with initializers handling ? */ - /* CPUs usually cannot use float constants, so we store them - generically in data segment */ -- size = type_size(&vtop->type, &align); -+ size = type_size(st, &vtop->type, &align); - offset = (data_section->data_offset + align - 1) & -align; - data_section->data_offset = offset; - /* XXX: not portable yet */ -- ptr = section_ptr_add(data_section, size); -+#ifdef __i386__ -+ /* long doubles are defined to be 96 bit wide by -+ the i386 ABI but the x87 only uses the first 80. The rest -+ is filled with garbage by now, so clear it before writing */ -+ if(size == 12) -+ vtop->c.tab[2] &= 0xffff; -+#endif -+ ptr = section_ptr_add(st, data_section, size); - size = size >> 2; -+#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) -+ check.d = 1; -+ if(check.tab[0]) -+ for(i=0;ic.tab[size-1-i]; -+ else -+#endif - for(i=0;ic.tab[i]; -- sym = get_sym_ref(&vtop->type, data_section, offset, size << 2); -+ sym = get_sym_ref(st, &vtop->type, data_section, offset, size << 2); - vtop->r |= VT_LVAL | VT_SYM; - vtop->sym = sym; - vtop->c.ul = 0; - } --#ifdef CONFIG_TCC_BCHECK -+#if 0 - if (vtop->r & VT_MUSTBOUND) -- gbound(); -+ gbound(st ); - #endif - - r = vtop->r & VT_VALMASK; -@@ -4798,7 +3980,7 @@ - !(reg_classes[r] & rc) || - ((vtop->type.t & VT_BTYPE) == VT_LLONG && - !(reg_classes[vtop->r2] & rc))) { -- r = get_reg(rc); -+ r = get_reg(st, rc); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - /* two register type load : expand to two words - temporarily */ -@@ -4806,30 +3988,30 @@ - /* load constant */ - ll = vtop->c.ull; - vtop->c.ui = ll; /* first word */ -- load(r, vtop); -+ load(st, r, vtop); - vtop->r = r; /* save register value */ -- vpushi(ll >> 32); /* second word */ -+ vpushi(st, ll >> 32); /* second word */ - } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ - (vtop->r & VT_LVAL)) { - /* We do not want to modifier the long long - pointer here, so the safest (and less - efficient) is to save all the other registers - in the stack. XXX: totally inefficient. */ -- save_regs(1); -+ save_regs(st, 1); - /* load from memory */ -- load(r, vtop); -- vdup(); -+ load(st, r, vtop); -+ vdup(st); - vtop[-1].r = r; /* save register value */ - /* increment pointer to get second word */ - vtop->type.t = VT_INT; -- gaddrof(); -- vpushi(4); -- gen_op('+'); -+ gaddrof(st); -+ vpushi(st, 4); -+ gen_op(st, '+'); - vtop->r |= VT_LVAL; - } else { - /* move registers */ -- load(r, vtop); -- vdup(); -+ load(st, r, vtop); -+ vdup(st ); - vtop[-1].r = r; /* save register value */ - vtop->r = vtop[-1].r2; - } -@@ -4837,12 +4019,12 @@ - rc2 = RC_INT; - if (rc == RC_IRET) - rc2 = RC_LRET; -- r2 = get_reg(rc2); -- load(r2, vtop); -- vpop(); -+ r2 = get_reg(st, rc2); -+ load(st, r2, vtop); -+ vpop(st); - /* write second register */ - vtop->r2 = r2; -- } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { -+ } else if ((vtop->r & VT_LVAL) && !is_float(st, vtop->type.t)) { - int t1, t; - /* lvalue of scalar type : need to use lvalue type - because of possible cast */ -@@ -4856,12 +4038,12 @@ - if (vtop->r & VT_LVAL_UNSIGNED) - t |= VT_UNSIGNED; - vtop->type.t = t; -- load(r, vtop); -+ load(st, r, vtop); - /* restore wanted type */ - vtop->type.t = t1; - } else { - /* one register type load */ -- load(r, vtop); -+ load(st, r, vtop); - } - } - vtop->r = r; -@@ -4875,7 +4057,7 @@ - } - - /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */ --void gv2(int rc1, int rc2) -+void gv2(TCCState *st, int rc1, int rc2) - { - int v; - -@@ -4884,36 +4066,36 @@ - reload errors */ - v = vtop[0].r & VT_VALMASK; - if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) { -- vswap(); -- gv(rc1); -- vswap(); -- gv(rc2); -+ vswap(st); -+ gv(st, rc1); -+ vswap(st); -+ gv(st, rc2); - /* test if reload is needed for first register */ - if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { -- vswap(); -- gv(rc1); -- vswap(); -+ vswap(st); -+ gv(st, rc1); -+ vswap(st); - } - } else { -- gv(rc2); -- vswap(); -- gv(rc1); -- vswap(); -+ gv(st, rc2); -+ vswap(st); -+ gv(st, rc1); -+ vswap(st); - /* test if reload is needed for first register */ - if ((vtop[0].r & VT_VALMASK) >= VT_CONST) { -- gv(rc2); -+ gv(st, rc2); - } - } - } - - /* expand long long on stack in two int registers */ --void lexpand(void) -+void lexpand(TCCState *st) - { - int u; - - u = vtop->type.t & VT_UNSIGNED; -- gv(RC_INT); -- vdup(); -+ gv(st, RC_INT); -+ vdup(st); - vtop[0].r = vtop[-1].r2; - vtop[0].r2 = VT_CONST; - vtop[-1].r2 = VT_CONST; -@@ -4928,7 +4110,7 @@ - int u,v; - - u = vtop->type.t & VT_UNSIGNED; -- vdup(); -+ vdup(st); - vtop->r2 = VT_CONST; - vtop->type.t = VT_INT | u; - v=vtop[-1].r & (VT_VALMASK | VT_LVAL); -@@ -4941,7 +4123,7 @@ - vtop->r = vtop[-1].r; - } else if (v > VT_CONST) { - vtop--; -- lexpand(); -+ lexpand(st); - } else - vtop->r = vtop[-1].r2; - vtop[-1].r2 = VT_CONST; -@@ -4950,18 +4132,18 @@ - #endif - - /* build a long long from two ints */ --void lbuild(int t) -+void lbuild(TCCState *st, int t) - { -- gv2(RC_INT, RC_INT); -+ gv2(st, RC_INT, RC_INT); - vtop[-1].r2 = vtop[0].r; - vtop[-1].type.t = t; -- vpop(); -+ vpop(st); - } - - /* rotate n first stack elements to the bottom - I1 ... In -> I2 ... In I1 [top is right] - */ --void vrotb(int n) -+void vrotb(TCCState *s, int n) - { - int i; - SValue tmp; -@@ -4975,7 +4157,7 @@ - /* rotate n first stack elements to the top - I1 ... In -> In I1 ... I(n-1) [top is right] - */ --void vrott(int n) -+void vrott(TCCState *s, int n) - { - int i; - SValue tmp; -@@ -4990,7 +4172,7 @@ - /* like vrott but in other direction - In ... I1 -> I(n-1) ... I1 In [top is right] - */ --void vnrott(int n) -+void vnrott(TCCState *s, int n) - { - int i; - SValue tmp; -@@ -5003,14 +4185,14 @@ - #endif - - /* pop stack value */ --void vpop(void) -+void vpop(TCCState *st) - { - int v; - v = vtop->r & VT_VALMASK; - #ifdef TCC_TARGET_I386 - /* for x86, we need to pop the FP stack */ -- if (v == TREG_ST0 && !nocode_wanted) { -- o(0xd9dd); /* fstp %st(1) */ -+ if (v == TREG_ST0) { -+ o(st, 0xd9dd); /* fstp %st(1) */ - } else - #endif - if (v == VT_JMP || v == VT_JMPI) { -@@ -5022,47 +4204,47 @@ - - /* convert stack entry to register and duplicate its value in another - register */ --void gv_dup(void) -+void gv_dup(TCCState *st) - { - int rc, t, r, r1; - SValue sv; - - t = vtop->type.t; - if ((t & VT_BTYPE) == VT_LLONG) { -- lexpand(); -- gv_dup(); -- vswap(); -- vrotb(3); -- gv_dup(); -- vrotb(4); -+ lexpand(st); -+ gv_dup(st); -+ vswap(st); -+ vrotb(st, 3); -+ gv_dup(st); -+ vrotb(st, 4); - /* stack: H L L1 H1 */ -- lbuild(t); -- vrotb(3); -- vrotb(3); -- vswap(); -- lbuild(t); -- vswap(); -+ lbuild(st, t); -+ vrotb(st, 3); -+ vrotb(st, 3); -+ vswap(st); -+ lbuild(st, t); -+ vswap(st); - } else { - /* duplicate value */ - rc = RC_INT; - sv.type.t = VT_INT; -- if (is_float(t)) { -+ if (is_float(st, t)) { - rc = RC_FLOAT; - sv.type.t = t; - } -- r = gv(rc); -- r1 = get_reg(rc); -+ r = gv(st, rc); -+ r1 = get_reg(st, rc); - sv.r = r; - sv.c.ul = 0; -- load(r1, &sv); /* move r to r1 */ -- vdup(); -+ load(st, r1, &sv); /* move r to r1 */ -+ vdup(st); - /* duplicates value */ - vtop->r = r1; - } - } - - /* generate CPU independent (unsigned) long long operations */ --void gen_opl(int op) -+void gen_opl(TCCState *st, int op) - { - int t, a, b, op1, c, i; - int func; -@@ -5083,10 +4265,10 @@ - func = TOK___umoddi3; - gen_func: - /* call generic long long function */ -- vpush_global_sym(&func_old_type, func); -- vrott(3); -- gfunc_call(2); -- vpushi(0); -+ vpush_global_sym(st, &func_old_type, func); -+ vrott(st, 3); -+ gfunc_call(st, 2); -+ vpushi(st, 0); - vtop->r = REG_IRET; - vtop->r2 = REG_LRET; - break; -@@ -5097,10 +4279,10 @@ - case '+': - case '-': - t = vtop->type.t; -- vswap(); -- lexpand(); -- vrotb(3); -- lexpand(); -+ vswap(st); -+ lexpand(st); -+ vrotb(st, 3); -+ lexpand(st); - /* stack: L1 H1 L2 H2 */ - tmp = vtop[0]; - vtop[0] = vtop[-3]; -@@ -5108,106 +4290,106 @@ - tmp = vtop[-2]; - vtop[-2] = vtop[-3]; - vtop[-3] = tmp; -- vswap(); -+ vswap(st); - /* stack: H1 H2 L1 L2 */ - if (op == '*') { -- vpushv(vtop - 1); -- vpushv(vtop - 1); -- gen_op(TOK_UMULL); -- lexpand(); -+ vpushv(st, vtop - 1); -+ vpushv(st, vtop - 1); -+ gen_op(st, TOK_UMULL); -+ lexpand(st); - /* stack: H1 H2 L1 L2 ML MH */ - for(i=0;i<4;i++) -- vrotb(6); -+ vrotb(st, 6); - /* stack: ML MH H1 H2 L1 L2 */ - tmp = vtop[0]; - vtop[0] = vtop[-2]; - vtop[-2] = tmp; - /* stack: ML MH H1 L2 H2 L1 */ -- gen_op('*'); -- vrotb(3); -- vrotb(3); -- gen_op('*'); -+ gen_op(st, '*'); -+ vrotb(st, 3); -+ vrotb(st, 3); -+ gen_op(st, '*'); - /* stack: ML MH M1 M2 */ -- gen_op('+'); -- gen_op('+'); -+ gen_op(st, '+'); -+ gen_op(st, '+'); - } else if (op == '+' || op == '-') { - /* XXX: add non carry method too (for MIPS or alpha) */ - if (op == '+') - op1 = TOK_ADDC1; - else - op1 = TOK_SUBC1; -- gen_op(op1); -+ gen_op(st, op1); - /* stack: H1 H2 (L1 op L2) */ -- vrotb(3); -- vrotb(3); -- gen_op(op1 + 1); /* TOK_xxxC2 */ -+ vrotb(st, 3); -+ vrotb(st, 3); -+ gen_op(st, op1 + 1); /* TOK_xxxC2 */ - } else { -- gen_op(op); -+ gen_op(st, op); - /* stack: H1 H2 (L1 op L2) */ -- vrotb(3); -- vrotb(3); -+ vrotb(st, 3); -+ vrotb(st, 3); - /* stack: (L1 op L2) H1 H2 */ -- gen_op(op); -+ gen_op(st, op); - /* stack: (L1 op L2) (H1 op H2) */ - } - /* stack: L H */ -- lbuild(t); -+ lbuild(st, t); - break; - case TOK_SAR: - case TOK_SHR: - case TOK_SHL: - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - t = vtop[-1].type.t; -- vswap(); -- lexpand(); -- vrotb(3); -+ vswap(st); -+ lexpand(st); -+ vrotb(st, 3); - /* stack: L H shift */ - c = (int)vtop->c.i; - /* constant: simpler */ - /* NOTE: all comments are for SHL. the other cases are - done by swaping words */ -- vpop(); -+ vpop(st); - if (op != TOK_SHL) -- vswap(); -+ vswap(st); - if (c >= 32) { - /* stack: L H */ -- vpop(); -+ vpop(st); - if (c > 32) { -- vpushi(c - 32); -- gen_op(op); -+ vpushi(st, c - 32); -+ gen_op(st, op); - } - if (op != TOK_SAR) { -- vpushi(0); -+ vpushi(st, 0); - } else { -- gv_dup(); -- vpushi(31); -- gen_op(TOK_SAR); -+ gv_dup(st); -+ vpushi(st, 31); -+ gen_op(st, TOK_SAR); - } -- vswap(); -+ vswap(st); - } else { -- vswap(); -- gv_dup(); -+ vswap(st); -+ gv_dup(st); - /* stack: H L L */ -- vpushi(c); -- gen_op(op); -- vswap(); -- vpushi(32 - c); -+ vpushi(st, c); -+ gen_op(st, op); -+ vswap(st); -+ vpushi(st, 32 - c); - if (op == TOK_SHL) -- gen_op(TOK_SHR); -+ gen_op(st, TOK_SHR); - else -- gen_op(TOK_SHL); -- vrotb(3); -+ gen_op(st, TOK_SHL); -+ vrotb(st, 3); - /* stack: L L H */ -- vpushi(c); -+ vpushi(st, c); - if (op == TOK_SHL) -- gen_op(TOK_SHL); -+ gen_op(st, TOK_SHL); - else -- gen_op(TOK_SHR); -- gen_op('|'); -+ gen_op(st, TOK_SHR); -+ gen_op(st, '|'); - } - if (op != TOK_SHL) -- vswap(); -- lbuild(t); -+ vswap(st); -+ lbuild(st, t); - } else { - /* XXX: should provide a faster fallback on x86 ? */ - switch(op) { -@@ -5226,10 +4408,10 @@ - default: - /* compare operations */ - t = vtop->type.t; -- vswap(); -- lexpand(); -- vrotb(3); -- lexpand(); -+ vswap(st); -+ lexpand(st); -+ vrotb(st, 3); -+ lexpand(st); - /* stack: L1 H1 L2 H2 */ - tmp = vtop[-1]; - vtop[-1] = vtop[-2]; -@@ -5249,23 +4431,23 @@ - op1 = TOK_UGE; - a = 0; - b = 0; -- gen_op(op1); -+ gen_op(st, op1); - if (op1 != TOK_NE) { -- a = gtst(1, 0); -+ a = gtst(st, 1, 0); - } - if (op != TOK_EQ) { - /* generate non equal test */ - /* XXX: NOT PORTABLE yet */ - if (a == 0) { -- b = gtst(0, 0); -+ b = gtst(st, 0, 0); - } else { - #if defined(TCC_TARGET_I386) -- b = psym(0x850f, 0); -+ b = psym(st, 0x850f, 0); - #elif defined(TCC_TARGET_ARM) - b = ind; -- o(0x1A000000 | encbranch(ind, 0, 1)); -+ o(st, 0x1A000000 | encbranch(ind, 0, 1)); - #elif defined(TCC_TARGET_C67) -- error("not implemented"); -+ tcc_error("not implemented"); - #else - #error not supported - #endif -@@ -5281,35 +4463,43 @@ - op1 = TOK_UGT; - else if (op1 == TOK_GE) - op1 = TOK_UGE; -- gen_op(op1); -- a = gtst(1, a); -+ gen_op(st, op1); -+ a = gtst(st, 1, a); - gsym(b); -- vseti(VT_JMPI, a); -+ vseti(st, VT_JMPI, a); - break; - } - } - --/* handle integer constant optimizations and various machine -- independent opt */ --void gen_opic(int op) -+/* handle long long constant and various machine independent optimizations */ -+void gen_opic(TCCState *st, int op) - { -- int fc, c1, c2, n; -+ int c1, c2, t1, t2; - SValue *v1, *v2; -+ long long l1, l2; - - v1 = vtop - 1; - v2 = vtop; -- /* currently, we cannot do computations with forward symbols */ -- c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; -- c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; -+ t1 = v1->type.t & VT_BTYPE; -+ t2 = v2->type.t & VT_BTYPE; -+ l1 = (t1 == VT_LLONG) ? v1->c.ll : v1->c.i; -+ l2 = (t2 == VT_LLONG) ? v2->c.ll : v2->c.i; -+ -+ /* For forward symbols we can only constify &&, || or == NULL */ -+ c2 = VT_SYM; -+ if (op == TOK_EQ && (v1->c.ll == 0 || v2->c.ll == 0)) c2 = 0; -+ if (op == TOK_LAND || op == TOK_LOR) c2 = 0; -+ c1 = (v1->r & (VT_VALMASK | VT_LVAL | c2)) == VT_CONST; -+ c2 = (v2->r & (VT_VALMASK | VT_LVAL | c2)) == VT_CONST; -+ - if (c1 && c2) { -- fc = v2->c.i; - switch(op) { -- case '+': v1->c.i += fc; break; -- case '-': v1->c.i -= fc; break; -- case '&': v1->c.i &= fc; break; -- case '^': v1->c.i ^= fc; break; -- case '|': v1->c.i |= fc; break; -- case '*': v1->c.i *= fc; break; -+ case '+': l1 += l2; break; -+ case '-': l1 -= l2; break; -+ case '&': l1 &= l2; break; -+ case '^': l1 ^= l2; break; -+ case '|': l1 |= l2; break; -+ case '*': l1 *= l2; break; - - case TOK_PDIV: - case '/': -@@ -5317,66 +4507,68 @@ - case TOK_UDIV: - case TOK_UMOD: - /* if division by zero, generate explicit division */ -- if (fc == 0) { -+ if (l2 == 0) { - if (const_wanted) -- error("division by zero in constant"); -+ tcc_error(st, "division by zero in constant"); - goto general_case; - } - switch(op) { -- default: v1->c.i /= fc; break; -- case '%': v1->c.i %= fc; break; -- case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break; -- case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break; -+ default: l1 /= l2; break; -+ case '%': l1 %= l2; break; -+ case TOK_UDIV: l1 = (unsigned long long)l1 / l2; break; -+ case TOK_UMOD: l1 = (unsigned long long)l1 % l2; break; - } - break; -- case TOK_SHL: v1->c.i <<= fc; break; -- case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break; -- case TOK_SAR: v1->c.i >>= fc; break; -+ case TOK_SHL: l1 <<= l2; break; -+ case TOK_SHR: l1 = (unsigned long long)l1 >> l2; break; -+ case TOK_SAR: l1 >>= l2; break; - /* tests */ -- case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break; -- case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break; -- case TOK_EQ: v1->c.i = v1->c.i == fc; break; -- case TOK_NE: v1->c.i = v1->c.i != fc; break; -- case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break; -- case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break; -- case TOK_LT: v1->c.i = v1->c.i < fc; break; -- case TOK_GE: v1->c.i = v1->c.i >= fc; break; -- case TOK_LE: v1->c.i = v1->c.i <= fc; break; -- case TOK_GT: v1->c.i = v1->c.i > fc; break; -+ case TOK_ULT: l1 = (unsigned long long)l1 < (unsigned long long)l2; break; -+ case TOK_UGE: l1 = (unsigned long long)l1 >= (unsigned long long)l2; break; -+ case TOK_EQ: l1 = l1 == l2; break; -+ case TOK_NE: l1 = l1 != l2; break; -+ case TOK_ULE: l1 = (unsigned long long)l1 <= (unsigned long long)l2; break; -+ case TOK_UGT: l1 = (unsigned long long)l1 > (unsigned long long)l2; break; -+ case TOK_LT: l1 = l1 < l2; break; -+ case TOK_GE: l1 = l1 >= l2; break; -+ case TOK_LE: l1 = l1 <= l2; break; -+ case TOK_GT: l1 = l1 > l2; break; - /* logical */ -- case TOK_LAND: v1->c.i = v1->c.i && fc; break; -- case TOK_LOR: v1->c.i = v1->c.i || fc; break; -+ case TOK_LAND: l1 = l1 && l2; break; -+ case TOK_LOR: l1 = l1 || l2; break; - default: - goto general_case; - } -+ v1->c.ll = l1; - vtop--; - } else { - /* if commutative ops, put c2 as constant */ - if (c1 && (op == '+' || op == '&' || op == '^' || - op == '|' || op == '*')) { -- vswap(); -+ vswap(st); - swap(&c1, &c2); -+ l2 = l1; - } -- fc = vtop->c.i; -+ /* Filter out NOP operations like x*1, x-0, x&-1... */ - if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || - op == TOK_PDIV) && -- fc == 1) || -+ l2 == 1) || - ((op == '+' || op == '-' || op == '|' || op == '^' || - op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && -- fc == 0) || -+ l2 == 0) || - (op == '&' && -- fc == -1))) { -+ l2 == -1))) { - /* nothing to do */ - vtop--; - } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { - /* try to use shifts instead of muls or divs */ -- if (fc > 0 && (fc & (fc - 1)) == 0) { -- n = -1; -- while (fc) { -- fc >>= 1; -+ if (l2 > 0 && (l2 & (l2 - 1)) == 0) { -+ int n = -1; -+ while (l2) { -+ l2 >>= 1; - n++; - } -- vtop->c.i = n; -+ vtop->c.ll = n; - if (op == '*') - op = TOK_SHL; - else if (op == TOK_PDIV) -@@ -5390,23 +4582,22 @@ - (VT_CONST | VT_SYM)) { - /* symbol + constant case */ - if (op == '-') -- fc = -fc; -+ l2 = -l2; - vtop--; -- vtop->c.i += fc; -+ vtop->c.ll += l2; - } else { - general_case: -- if (!nocode_wanted) { - /* call low level op generator */ -- gen_opi(op); -- } else { -- vtop--; -- } -+ if (cur_text_section) { -+ if (t1 == VT_LLONG|| t2 == VT_LLONG) gen_opl(st, op); -+ else gen_opi(st, op); -+ } else vtop--; - } - } - } - - /* generate a floating point operation with constant propagation */ --void gen_opif(int op) -+void gen_opif(TCCState *st, int op) - { - int c1, c2; - SValue *v1, *v2; -@@ -5431,7 +4622,7 @@ - - /* NOTE: we only do constant propagation if finite number (not - NaN or infinity) (ANSI spec) */ -- if (!ieee_finite(f1) || !ieee_finite(f2)) -+ if (!ieee_finite(st, f1) || !ieee_finite(st, f2)) - goto general_case; - - switch(op) { -@@ -5441,7 +4632,7 @@ - case '/': - if (f2 == 0.0) { - if (const_wanted) -- error("division by zero in constant"); -+ tcc_error(st, "division by zero in constant"); - goto general_case; - } - f1 /= f2; -@@ -5461,21 +4652,18 @@ - vtop--; - } else { - general_case: -- if (!nocode_wanted) { -- gen_opf(op); -- } else { -- vtop--; -- } -+ if (cur_text_section) gen_opf(st, op); -+ else vtop--; - } - } - --static int pointed_size(CType *type) -+static int pointed_size(TCCState *st, CType *type) - { - int align; -- return type_size(pointed_type(type), &align); -+ return type_size(st, pointed_type(st, type), &align); - } - --static inline int is_null_pointer(SValue *p) -+static inline int is_null_pointer(TCCState *st, SValue *p) - { - if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) - return 0; -@@ -5483,42 +4671,43 @@ - ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0); - } - --static inline int is_integer_btype(int bt) -+static inline int is_integer_btype(TCCState *st, int bt) - { - return (bt == VT_BYTE || bt == VT_SHORT || - bt == VT_INT || bt == VT_LLONG); - } - - /* check types for comparison or substraction of pointers */ --static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) -+static void check_comparison_pointer_types(TCCState *st, SValue *p1, SValue *p2, int op) - { - CType *type1, *type2, tmp_type1, tmp_type2; - int bt1, bt2; - - /* null pointers are accepted for all comparisons as gcc */ -- if (is_null_pointer(p1) || is_null_pointer(p2)) -+ if (is_null_pointer(st, p1) || is_null_pointer(st, p2)) - return; - type1 = &p1->type; - type2 = &p2->type; - bt1 = type1->t & VT_BTYPE; - bt2 = type2->t & VT_BTYPE; - /* accept comparison between pointer and integer with a warning */ -- if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') { -- warning("comparison between pointer and integer"); -+ if ((is_integer_btype(st, bt1) || is_integer_btype(st, bt2)) && op != '-') { -+ if (op != TOK_LOR && op != TOK_LAND ) -+ warning(st, "comparison between pointer and integer"); - return; - } - - /* both must be pointers or implicit function pointers */ - if (bt1 == VT_PTR) { -- type1 = pointed_type(type1); -+ type1 = pointed_type(st, type1); - } else if (bt1 != VT_FUNC) - goto invalid_operands; - - if (bt2 == VT_PTR) { -- type2 = pointed_type(type2); -+ type2 = pointed_type(st, type2); - } else if (bt2 != VT_FUNC) { - invalid_operands: -- error("invalid operands to binary %s", get_tok_str(op, NULL)); -+ tcc_error(st, "invalid operands to binary %s", get_tok_str(st, op, NULL)); - } - if ((type1->t & VT_BTYPE) == VT_VOID || - (type2->t & VT_BTYPE) == VT_VOID) -@@ -5527,17 +4716,17 @@ - tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); -- if (!is_compatible_types(&tmp_type1, &tmp_type2)) { -+ if (!is_compatible_types(st, &tmp_type1, &tmp_type2)) { - /* gcc-like error if '-' is used */ - if (op == '-') - goto invalid_operands; - else -- warning("comparison of distinct pointer types lacks a cast"); -+ warning(st, "comparison of distinct pointer types lacks a cast"); - } - } - - /* generic gen_op: handles types problems */ --void gen_op(int op) -+void gen_op(TCCState *st, int op) - { - int u, t1, t2, bt1, bt2, t; - CType type1; -@@ -5550,8 +4739,8 @@ - if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* at least one operand is a pointer */ - /* relationnal op: must be both pointers */ -- if (op >= TOK_ULT && op <= TOK_GT) { -- check_comparison_pointer_types(vtop - 1, vtop, op); -+ if (op >= TOK_ULT && op <= TOK_LOR) { -+ check_comparison_pointer_types(st, vtop - 1, vtop, op); - /* pointers are handled are unsigned */ - t = VT_INT | VT_UNSIGNED; - goto std_op; -@@ -5559,49 +4748,49 @@ - /* if both pointers, then it must be the '-' op */ - if (bt1 == VT_PTR && bt2 == VT_PTR) { - if (op != '-') -- error("cannot use pointers here"); -- check_comparison_pointer_types(vtop - 1, vtop, op); -+ tcc_error(st, "cannot use pointers here"); -+ check_comparison_pointer_types(st, vtop - 1, vtop, op); - /* XXX: check that types are compatible */ -- u = pointed_size(&vtop[-1].type); -- gen_opic(op); -+ u = pointed_size(st, &vtop[-1].type); -+ gen_opic(st, op); - /* set to integer type */ - vtop->type.t = VT_INT; -- vpushi(u); -- gen_op(TOK_PDIV); -+ vpushi(st, u); -+ gen_op(st, TOK_PDIV); - } else { - /* exactly one pointer : must be '+' or '-'. */ - if (op != '-' && op != '+') -- error("cannot use pointers here"); -+ tcc_error(st, "cannot use pointers here"); - /* Put pointer as first operand */ - if (bt2 == VT_PTR) { -- vswap(); -+ vswap(st); - swap(&t1, &t2); - } - type1 = vtop[-1].type; - /* XXX: cast to int ? (long long case) */ -- vpushi(pointed_size(&vtop[-1].type)); -- gen_op('*'); --#ifdef CONFIG_TCC_BCHECK -+ vpushi(st, pointed_size(st, &vtop[-1].type)); -+ gen_op(st, '*'); -+#if 0 - /* if evaluating constant expression, no code should be - generated, so no bound check */ - if (do_bounds_check && !const_wanted) { - /* if bounded pointers, we generate a special code to - test bounds */ - if (op == '-') { -- vpushi(0); -- vswap(); -- gen_op('-'); -+ vpushi(st, 0); -+ vswap(st); -+ gen_op(st, '-'); - } -- gen_bounded_ptr_add(); -+ gen_bounded_ptr_add(st); - } else - #endif - { -- gen_opic(op); -+ gen_opic(st, op); - } -- /* put again type if gen_opic() swaped operands */ -+ /* put again type if gen_opic(st) swaped operands */ - vtop->type = type1; - } -- } else if (is_float(bt1) || is_float(bt2)) { -+ } else if (is_float(st, bt1) || is_float(st, bt2)) { - /* compute bigger type and do implicit casts */ - if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { - t = VT_LDOUBLE; -@@ -5613,7 +4802,7 @@ - /* floats can only be used for a few operations */ - if (op != '+' && op != '-' && op != '*' && op != '/' && - (op < TOK_ULT || op > TOK_GT)) -- error("invalid operands for binary operation"); -+ tcc_error(st, "invalid operands for binary operation"); - goto std_op; - } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { - /* cast to biggest op */ -@@ -5649,21 +4838,19 @@ - else if (op == TOK_GE) - op = TOK_UGE; - } -- vswap(); -+ vswap(st); - type1.t = t; -- gen_cast(&type1); -- vswap(); -+ gen_cast(st, &type1); -+ vswap(st); - /* special case for shifts and long long: we keep the shift as - an integer */ - if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) - type1.t = VT_INT; -- gen_cast(&type1); -- if (is_float(t)) -- gen_opif(op); -- else if ((t & VT_BTYPE) == VT_LLONG) -- gen_opl(op); -+ gen_cast(st, &type1); -+ if (is_float(st, t)) -+ gen_opif(st, op); - else -- gen_opic(op); -+ gen_opic(st, op); - if (op >= TOK_ULT && op <= TOK_GT) { - /* relationnal op: the result is an int */ - vtop->type.t = VT_INT; -@@ -5674,28 +4861,28 @@ - } - - /* generic itof for unsigned long long case */ --void gen_cvt_itof1(int t) -+void gen_cvt_itof1(TCCState *st, int t) - { - if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == - (VT_LLONG | VT_UNSIGNED)) { - - if (t == VT_FLOAT) -- vpush_global_sym(&func_old_type, TOK___ulltof); -+ vpush_global_sym(st, &func_old_type, TOK___ulltof); - else if (t == VT_DOUBLE) -- vpush_global_sym(&func_old_type, TOK___ulltod); -+ vpush_global_sym(st, &func_old_type, TOK___ulltod); - else -- vpush_global_sym(&func_old_type, TOK___ulltold); -- vrott(2); -- gfunc_call(1); -- vpushi(0); -+ vpush_global_sym(st, &func_old_type, TOK___ulltold); -+ vrott(st, 2); -+ gfunc_call(st, 1); -+ vpushi(st, 0); - vtop->r = REG_FRET; - } else { -- gen_cvt_itof(t); -+ gen_cvt_itof(st, t); - } - } - - /* generic ftoi for unsigned long long case */ --void gen_cvt_ftoi1(int t) -+void gen_cvt_ftoi1(TCCState *state, int t) - { - int st; - -@@ -5703,23 +4890,23 @@ - /* not handled natively */ - st = vtop->type.t & VT_BTYPE; - if (st == VT_FLOAT) -- vpush_global_sym(&func_old_type, TOK___fixunssfdi); -+ vpush_global_sym(state, &func_old_type, TOK___fixunssfdi); - else if (st == VT_DOUBLE) -- vpush_global_sym(&func_old_type, TOK___fixunsdfdi); -+ vpush_global_sym(state, &func_old_type, TOK___fixunsdfdi); - else -- vpush_global_sym(&func_old_type, TOK___fixunsxfdi); -- vrott(2); -- gfunc_call(1); -- vpushi(0); -+ vpush_global_sym(state, &func_old_type, TOK___fixunsxfdi); -+ vrott(state, 2); -+ gfunc_call(state, 1); -+ vpushi(state, 0); - vtop->r = REG_IRET; - vtop->r2 = REG_LRET; - } else { -- gen_cvt_ftoi(t); -+ gen_cvt_ftoi(state, t); - } - } - - /* force char or short cast */ --void force_charshort_cast(int t) -+void force_charshort_cast(TCCState *st, int t) - { - int bits, dbt; - dbt = t & VT_BTYPE; -@@ -5729,19 +4916,24 @@ - else - bits = 16; - if (t & VT_UNSIGNED) { -- vpushi((1 << bits) - 1); -- gen_op('&'); -+ vpushi(st, (1 << bits) - 1); -+ gen_op(st, '&'); - } else { - bits = 32 - bits; -- vpushi(bits); -- gen_op(TOK_SHL); -- vpushi(bits); -- gen_op(TOK_SAR); -+ vpushi(st, bits); -+ gen_op(st, TOK_SHL); -+ /* result must be signed or the SAR is converted to an SHL -+ This was not the case when "t" was a signed short -+ and the last value on the stack was an unsigned int -+ */ -+ vtop->type.t &= (~VT_UNSIGNED); -+ vpushi(st, bits); -+ gen_op(st, TOK_SAR); - } - } - - /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ --static void gen_cast(CType *type) -+static void gen_cast(TCCState *st, CType *type) - { - int sbt, dbt, sf, df, c; - -@@ -5750,20 +4942,20 @@ - be incorrect */ - if (vtop->r & VT_MUSTCAST) { - vtop->r &= ~VT_MUSTCAST; -- force_charshort_cast(vtop->type.t); -+ force_charshort_cast(st, vtop->type.t); - } - - /* bitfields first get cast to ints */ - if (vtop->type.t & VT_BITFIELD) { -- gv(RC_INT); -+ gv(st, RC_INT); - } - - dbt = type->t & (VT_BTYPE | VT_UNSIGNED); - sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); - -- if (sbt != dbt && !nocode_wanted) { -- sf = is_float(sbt); -- df = is_float(dbt); -+ if (sbt != dbt && cur_text_section) { -+ sf = is_float(st, sbt); -+ df = is_float(st, dbt); - c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - if (sf && df) { - /* convert from fp to fp */ -@@ -5784,7 +4976,7 @@ - vtop->c.ld = (long double)vtop->c.d; - } else { - /* non constant case: generate code */ -- gen_cvt_ftof(dbt); -+ gen_cvt_ftof(st, dbt); - } - } else if (df) { - /* convert int to fp */ -@@ -5812,13 +5004,17 @@ - } else { - do_itof: - #if !defined(TCC_TARGET_ARM) -- gen_cvt_itof1(dbt); -+ gen_cvt_itof1(st, dbt); - #else -- gen_cvt_itof(dbt); -+ gen_cvt_itof(st, dbt); - #endif - } - } else if (sf) { - /* convert fp to int */ -+ if (dbt == VT_BOOL) { -+ vpushi(st, 0); -+ gen_op(st, TOK_NE); -+ } else { - /* we handle char/short/etc... with generic code */ - if (dbt != (VT_INT | VT_UNSIGNED) && - dbt != (VT_LLONG | VT_UNSIGNED) && -@@ -5848,12 +5044,13 @@ - } - } else { - do_ftoi: -- gen_cvt_ftoi1(dbt); -+ gen_cvt_ftoi1(st, dbt); - } - if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { -- /* additional cast for char/short/bool... */ -+ /* additional cast for char/short... */ - vtop->type.t = dbt; -- gen_cast(type); -+ gen_cast(st, type); -+ } - } - } else if ((dbt & VT_BTYPE) == VT_LLONG) { - if ((sbt & VT_BTYPE) != VT_LLONG) { -@@ -5865,45 +5062,54 @@ - vtop->c.ll = vtop->c.i; - } else { - /* machine independent conversion */ -- gv(RC_INT); -+ gv(st, RC_INT); - /* generate high word */ - if (sbt == (VT_INT | VT_UNSIGNED)) { -- vpushi(0); -- gv(RC_INT); -+ vpushi(st, 0); -+ gv(st, RC_INT); - } else { -- gv_dup(); -- vpushi(31); -- gen_op(TOK_SAR); -+ gv_dup(st); -+ vpushi(st, 31); -+ gen_op(st, TOK_SAR); - } - /* patch second register */ - vtop[-1].r2 = vtop->r; -- vpop(); -+ vpop(st); - } - } - } else if (dbt == VT_BOOL) { - /* scalar to bool */ -- vpushi(0); -- gen_op(TOK_NE); -+ vpushi(st, 0); -+ gen_op(st, TOK_NE); - } else if ((dbt & VT_BTYPE) == VT_BYTE || - (dbt & VT_BTYPE) == VT_SHORT) { -- force_charshort_cast(dbt); -+ if (sbt == VT_PTR) { -+ vtop->type.t = VT_INT; -+ warning(st, "nonportable conversion from pointer to char/short"); -+ } -+ force_charshort_cast(st, dbt); - } else if ((dbt & VT_BTYPE) == VT_INT) { - /* scalar to int */ - if (sbt == VT_LLONG) { - /* from long long: just take low order word */ -- lexpand(); -- vpop(); -+ lexpand(st); -+ vpop(st); - } - /* if lvalue and single word type, nothing to do because - the lvalue already contains the real type size (see - VT_LVAL_xxx constants) */ - } -+ } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) { -+ /* if we are casting between pointer types, -+ we must update the VT_LVAL_xxx size */ -+ vtop->r = (vtop->r & ~VT_LVAL_TYPE) -+ | (lvalue_type(st, type->ref->type.t) & VT_LVAL_TYPE); - } - vtop->type = *type; - } - - /* return type size. Put alignment at 'a' */ --static int type_size(CType *type, int *a) -+static int type_size(TCCState *st, CType *type, int *a) - { - Sym *s; - int bt; -@@ -5917,7 +5123,7 @@ - } else if (bt == VT_PTR) { - if (type->t & VT_ARRAY) { - s = type->ref; -- return type_size(&s->type, a) * s->c; -+ return type_size(st, &s->type, a) * s->c; - } else { - *a = PTR_SIZE; - return PTR_SIZE; -@@ -5928,6 +5134,12 @@ - } else if (bt == VT_DOUBLE || bt == VT_LLONG) { - #ifdef TCC_TARGET_I386 - *a = 4; -+#elif defined(TCC_TARGET_ARM) -+#ifdef TCC_ARM_EABI -+ *a = 8; -+#else -+ *a = 4; -+#endif - #else - *a = 8; - #endif -@@ -5946,43 +5158,43 @@ - } - - /* return the pointed type of t */ --static inline CType *pointed_type(CType *type) -+static inline CType *pointed_type(TCCState *st, CType *type) - { - return &type->ref->type; - } - - /* modify type so that its it is a pointer to type. */ --static void mk_pointer(CType *type) -+static void mk_pointer(TCCState *st, CType *type) - { - Sym *s; -- s = sym_push(SYM_FIELD, type, 0, -1); -+ s = sym_push(st, SYM_FIELD, type, 0, -1); - type->t = VT_PTR | (type->t & ~VT_TYPE); - type->ref = s; - } - - /* compare function types. OLD functions match any new functions */ --static int is_compatible_func(CType *type1, CType *type2) -+static int is_compatible_func(TCCState *state, CType *type1, CType *type2) - { -- Sym *s1, *s2; -+ Sym *st, *s2; - -- s1 = type1->ref; -+ st = type1->ref; - s2 = type2->ref; -- if (!is_compatible_types(&s1->type, &s2->type)) -+ if (!is_compatible_types(state, &st->type, &s2->type)) - return 0; - /* check func_call */ -- if (s1->r != s2->r) -+ if (st->r != s2->r) - return 0; - /* XXX: not complete */ -- if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) -+ if (st->c == FUNC_OLD || s2->c == FUNC_OLD) - return 1; -- if (s1->c != s2->c) -+ if (st->c != s2->c) - return 0; -- while (s1 != NULL) { -+ while (st != NULL) { - if (s2 == NULL) - return 0; -- if (!is_compatible_types(&s1->type, &s2->type)) -+ if (!is_compatible_types(state, &st->type, &s2->type)) - return 0; -- s1 = s1->next; -+ st = st->next; - s2 = s2->next; - } - if (s2) -@@ -5993,9 +5205,9 @@ - /* return true if type1 and type2 are exactly the same (including - qualifiers). - -- - enums are not checked as gcc __builtin_types_compatible_p () -+ - enums are not checked as gcc __builtin_types_compatible_p (st) - */ --static int is_compatible_types(CType *type1, CType *type2) -+static int is_compatible_types(TCCState *st, CType *type1, CType *type2) - { - int bt1, t1, t2; - -@@ -6007,13 +5219,13 @@ - /* test more complicated cases */ - bt1 = t1 & VT_BTYPE; - if (bt1 == VT_PTR) { -- type1 = pointed_type(type1); -- type2 = pointed_type(type2); -- return is_compatible_types(type1, type2); -+ type1 = pointed_type(st, type1); -+ type2 = pointed_type(st, type2); -+ return is_compatible_types(st, type1, type2); - } else if (bt1 == VT_STRUCT) { - return (type1->ref == type2->ref); - } else if (bt1 == VT_FUNC) { -- return is_compatible_func(type1, type2); -+ return is_compatible_func(st, type1, type2); - } else { - return 1; - } -@@ -6023,7 +5235,7 @@ - printed in the type */ - /* XXX: union */ - /* XXX: add array and function pointers */ --void type_to_str(char *buf, int buf_size, -+void type_to_str(TCCState *st, char *buf, int buf_size, - CType *type, const char *varstr) - { - int bt, v, t; -@@ -6035,11 +5247,11 @@ - bt = t & VT_BTYPE; - buf[0] = '\0'; - if (t & VT_CONSTANT) -- pstrcat(buf, buf_size, "const "); -+ pstrcat(st, buf, buf_size, "const "); - if (t & VT_VOLATILE) -- pstrcat(buf, buf_size, "volatile "); -+ pstrcat(st, buf, buf_size, "volatile "); - if (t & VT_UNSIGNED) -- pstrcat(buf, buf_size, "unsigned "); -+ pstrcat(st, buf, buf_size, "unsigned "); - switch(bt) { - case VT_VOID: - tstr = "void"; -@@ -6071,7 +5283,7 @@ - case VT_LDOUBLE: - tstr = "long double"; - add_tstr: -- pstrcat(buf, buf_size, tstr); -+ pstrcat(st, buf, buf_size, tstr); - break; - case VT_ENUM: - case VT_STRUCT: -@@ -6079,45 +5291,45 @@ - tstr = "struct "; - else - tstr = "enum "; -- pstrcat(buf, buf_size, tstr); -+ pstrcat(st, buf, buf_size, tstr); - v = type->ref->v & ~SYM_STRUCT; - if (v >= SYM_FIRST_ANOM) -- pstrcat(buf, buf_size, ""); -+ pstrcat(st, buf, buf_size, ""); - else -- pstrcat(buf, buf_size, get_tok_str(v, NULL)); -+ pstrcat(st, buf, buf_size, get_tok_str(st, v, NULL)); - break; - case VT_FUNC: - s = type->ref; -- type_to_str(buf, buf_size, &s->type, varstr); -- pstrcat(buf, buf_size, "("); -+ type_to_str(st, buf, buf_size, &s->type, varstr); -+ pstrcat(st, buf, buf_size, "("); - sa = s->next; - while (sa != NULL) { -- type_to_str(buf1, sizeof(buf1), &sa->type, NULL); -- pstrcat(buf, buf_size, buf1); -+ type_to_str(st, buf1, sizeof(buf1), &sa->type, NULL); -+ pstrcat(st, buf, buf_size, buf1); - sa = sa->next; - if (sa) -- pstrcat(buf, buf_size, ", "); -+ pstrcat(st, buf, buf_size, ", "); - } -- pstrcat(buf, buf_size, ")"); -+ pstrcat(st, buf, buf_size, ")"); - goto no_var; - case VT_PTR: - s = type->ref; -- pstrcpy(buf1, sizeof(buf1), "*"); -+ pstrcpy(st, buf1, sizeof(buf1), "*"); - if (varstr) -- pstrcat(buf1, sizeof(buf1), varstr); -- type_to_str(buf, buf_size, &s->type, buf1); -+ pstrcat(st, buf1, sizeof(buf1), varstr); -+ type_to_str(st, buf, buf_size, &s->type, buf1); - goto no_var; - } - if (varstr) { -- pstrcat(buf, buf_size, " "); -- pstrcat(buf, buf_size, varstr); -+ pstrcat(st, buf, buf_size, " "); -+ pstrcat(st, buf, buf_size, varstr); - } - no_var: ; - } - - /* verify type compatibility to store vtop in 'dt' type, and generate - casts if needed. */ --static void gen_assign_cast(CType *dt) -+static void gen_assign_cast(TCCState *state, CType *dt) - { - CType *st, *type1, *type2, tmp_type1, tmp_type2; - char buf1[256], buf2[256]; -@@ -6127,30 +5339,30 @@ - dbt = dt->t & VT_BTYPE; - sbt = st->t & VT_BTYPE; - if (dt->t & VT_CONSTANT) -- warning("assignment of read-only location"); -+ warning(state, "assignment of read-only location"); - switch(dbt) { - case VT_PTR: - /* special cases for pointers */ - /* '0' can also be a pointer */ -- if (is_null_pointer(vtop)) -+ if (is_null_pointer(state, vtop)) - goto type_ok; - /* accept implicit pointer to integer cast with warning */ -- if (is_integer_btype(sbt)) { -- warning("assignment makes pointer from integer without a cast"); -+ if (is_integer_btype(state, sbt)) { -+ warning(state, "assignment makes pointer from integer without a cast"); - goto type_ok; - } -- type1 = pointed_type(dt); -+ type1 = pointed_type(state, dt); - /* a function is implicitely a function pointer */ - if (sbt == VT_FUNC) { - if ((type1->t & VT_BTYPE) != VT_VOID && -- !is_compatible_types(pointed_type(dt), st)) -+ !is_compatible_types(state, pointed_type(state, dt), st)) - goto error; - else - goto type_ok; - } - if (sbt != VT_PTR) - goto error; -- type2 = pointed_type(st); -+ type2 = pointed_type(state, st); - if ((type1->t & VT_BTYPE) == VT_VOID || - (type2->t & VT_BTYPE) == VT_VOID) { - /* void * can match anything */ -@@ -6160,20 +5372,20 @@ - tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); -- if (!is_compatible_types(&tmp_type1, &tmp_type2)) -- goto error; -+ if (!is_compatible_types(state, &tmp_type1, &tmp_type2)) -+ warning(state, "assignment from incompatible pointer type"); - } - /* check const and volatile */ - if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || - (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE))) -- warning("assignment discards qualifiers from pointer target type"); -+ warning(state, "assignment discards qualifiers from pointer target type"); - break; - case VT_BYTE: - case VT_SHORT: - case VT_INT: - case VT_LLONG: - if (sbt == VT_PTR || sbt == VT_FUNC) { -- warning("assignment makes integer from pointer without a cast"); -+ warning(state, "assignment makes integer from pointer without a cast"); - } - /* XXX: more tests */ - break; -@@ -6182,20 +5394,20 @@ - tmp_type2 = *st; - tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); -- if (!is_compatible_types(&tmp_type1, &tmp_type2)) { -+ if (!is_compatible_types(state, &tmp_type1, &tmp_type2)) { - error: -- type_to_str(buf1, sizeof(buf1), st, NULL); -- type_to_str(buf2, sizeof(buf2), dt, NULL); -- error("cannot cast '%s' to '%s'", buf1, buf2); -+ type_to_str(state, buf1, sizeof(buf1), st, NULL); -+ type_to_str(state, buf2, sizeof(buf2), dt, NULL); -+ tcc_error(state, "cannot cast '%s' to '%s'", buf1, buf2); - } - break; - } - type_ok: -- gen_cast(dt); -+ gen_cast(state, dt); - } - - /* store vtop in lvalue pushed on stack */ --void vstore(void) -+void vstore(TCCState *st) - { - int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; - -@@ -6209,39 +5421,46 @@ - vtop->type.t = ft & VT_TYPE; - /* XXX: factorize */ - if (ft & VT_CONSTANT) -- warning("assignment of read-only location"); -+ warning(st, "assignment of read-only location"); - } else { - delayed_cast = 0; - if (!(ft & VT_BITFIELD)) -- gen_assign_cast(&vtop[-1].type); -+ gen_assign_cast(st, &vtop[-1].type); - } - - if (sbt == VT_STRUCT) { - /* if structure, only generate pointer */ - /* structure assignment : generate memcpy */ - /* XXX: optimize if small size */ -- if (!nocode_wanted) { -- size = type_size(&vtop->type, &align); -+ if (cur_text_section) { -+ size = type_size(st, &vtop->type, &align); - -- vpush_global_sym(&func_old_type, TOK_memcpy); -+#ifdef TCC_ARM_EABI -+ if(!(align & 7)) -+ vpush_global_sym(st, &func_old_type, TOK_memcpy8); -+ else if(!(align & 3)) -+ vpush_global_sym(st, &func_old_type, TOK_memcpy4); -+ else -+#endif -+ vpush_global_sym(st, &func_old_type, TOK_memcpy); - - /* destination */ -- vpushv(vtop - 2); -+ vpushv(st, vtop - 2); - vtop->type.t = VT_INT; -- gaddrof(); -+ gaddrof(st); - /* source */ -- vpushv(vtop - 2); -+ vpushv(st, vtop - 2); - vtop->type.t = VT_INT; -- gaddrof(); -+ gaddrof(st); - /* type size */ -- vpushi(size); -- gfunc_call(3); -+ vpushi(st, size); -+ gfunc_call(st, 3); - -- vswap(); -- vpop(); -+ vswap(st); -+ vpop(st); - } else { -- vswap(); -- vpop(); -+ vswap(st); -+ vpop(st); - } - /* leave source on stack */ - } else if (ft & VT_BITFIELD) { -@@ -6251,83 +5470,92 @@ - /* remove bit field info to avoid loops */ - vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - -+ /* duplicate source into other register */ -+ gv_dup(st); -+ vswap(st); -+ vrott(st, 3); -+ - /* duplicate destination */ -- vdup(); -+ vdup(st); - vtop[-1] = vtop[-2]; - - /* mask and shift source */ -- vpushi((1 << bit_size) - 1); -- gen_op('&'); -- vpushi(bit_pos); -- gen_op(TOK_SHL); -+ vpushi(st, (1 << bit_size) - 1); -+ gen_op(st, '&'); -+ vpushi(st, bit_pos); -+ gen_op(st, TOK_SHL); - /* load destination, mask and or with source */ -- vswap(); -- vpushi(~(((1 << bit_size) - 1) << bit_pos)); -- gen_op('&'); -- gen_op('|'); -+ vswap(st); -+ vpushi(st, ~(((1 << bit_size) - 1) << bit_pos)); -+ gen_op(st, '&'); -+ gen_op(st, '|'); - /* store result */ -- vstore(); -+ vstore(st); -+ -+ /* pop off shifted source from "duplicate source..." above */ -+ vpop(st); -+ - } else { --#ifdef CONFIG_TCC_BCHECK -+#if 0 - /* bound check case */ - if (vtop[-1].r & VT_MUSTBOUND) { -- vswap(); -- gbound(); -- vswap(); -+ vswap(st); -+ gbound(st); -+ vswap(st); - } - #endif -- if (!nocode_wanted) { -+ if (cur_text_section) { - rc = RC_INT; -- if (is_float(ft)) -+ if (is_float(st, ft)) - rc = RC_FLOAT; -- r = gv(rc); /* generate value */ -+ r = gv(st, rc); /* generate value */ - /* if lvalue was saved on stack, must read it */ - if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) { - SValue sv; -- t = get_reg(RC_INT); -+ t = get_reg(st, RC_INT); - sv.type.t = VT_INT; - sv.r = VT_LOCAL | VT_LVAL; - sv.c.ul = vtop[-1].c.ul; -- load(t, &sv); -+ load(st, t, &sv); - vtop[-1].r = t | VT_LVAL; - } -- store(r, vtop - 1); -+ store(st, r, vtop - 1); - /* two word case handling : store second register at word + 4 */ - if ((ft & VT_BTYPE) == VT_LLONG) { -- vswap(); -+ vswap(st); - /* convert to int to increment easily */ - vtop->type.t = VT_INT; -- gaddrof(); -- vpushi(4); -- gen_op('+'); -+ gaddrof(st); -+ vpushi(st, 4); -+ gen_op(st, '+'); - vtop->r |= VT_LVAL; -- vswap(); -+ vswap(st); - /* XXX: it works because r2 is spilled last ! */ -- store(vtop->r2, vtop - 1); -+ store(st, vtop->r2, vtop - 1); - } - } -- vswap(); -- vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ -+ vswap(st); -+ vtop--; /* NOT vpop(st) because on x86 it would flush the fp stack */ - vtop->r |= delayed_cast; - } - } - - /* post defines POST/PRE add. c is the token ++ or -- */ --void inc(int post, int c) -+void inc(TCCState *st, int post, int c) - { -- test_lvalue(); -- vdup(); /* save lvalue */ -+ test_lvalue(st); -+ vdup(st); /* save lvalue */ - if (post) { -- gv_dup(); /* duplicate value */ -- vrotb(3); -- vrotb(3); -+ gv_dup(st); /* duplicate value */ -+ vrotb(st, 3); -+ vrotb(st, 3); - } - /* add constant */ -- vpushi(c - TOK_MID); -- gen_op('+'); -- vstore(); /* store value */ -+ vpushi(st, c - TOK_MID); -+ gen_op(st, '+'); -+ vstore(st); /* store value */ - if (post) -- vpop(); /* if post op, return saved value */ -+ vpop(st); /* if post op, return saved value */ - } - - /* Parse GNUC __attribute__ extension. Currently, the following -@@ -6338,37 +5566,37 @@ - - unused : currently ignored, but may be used someday. - - regparm(n) : pass function parameters in registers (i386 only) - */ --static void parse_attribute(AttributeDef *ad) -+static void parse_attribute(TCCState *st, AttributeDef *ad) - { - int t, n; - - while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { -- next(); -- skip('('); -- skip('('); -+ next(st); -+ skip(st, '('); -+ skip(st, '('); - while (tok != ')') { - if (tok < TOK_IDENT) -- expect("attribute name"); -+ expect(st, "attribute name"); - t = tok; -- next(); -+ next(st); - switch(t) { - case TOK_SECTION1: - case TOK_SECTION2: -- skip('('); -+ skip(st, '('); - if (tok != TOK_STR) -- expect("section name"); -- ad->section = find_section(tcc_state, (char *)tokc.cstr->data); -- next(); -- skip(')'); -+ expect(st, "section name"); -+ ad->section = find_section(st, (char *)tokc.cstr->data); -+ next(st); -+ skip(st, ')'); - break; - case TOK_ALIGNED1: - case TOK_ALIGNED2: - if (tok == '(') { -- next(); -- n = expr_const(); -+ next(st); -+ n = expr_const(st); - if (n <= 0 || (n & (n - 1)) != 0) -- error("alignment must be a positive power of two"); -- skip(')'); -+ tcc_error(st, "alignment must be a positive power of two"); -+ skip(st, ')'); - } else { - n = MAX_ALIGN; - } -@@ -6401,63 +5629,69 @@ - #ifdef TCC_TARGET_I386 - case TOK_REGPARM1: - case TOK_REGPARM2: -- skip('('); -- n = expr_const(); -+ skip(st, '('); -+ n = expr_const(st); - if (n > 3) - n = 3; - else if (n < 0) - n = 0; - if (n > 0) - ad->func_call = FUNC_FASTCALL1 + n - 1; -- skip(')'); -+ skip(st, ')'); -+ break; -+ case TOK_FASTCALL1: -+ case TOK_FASTCALL2: -+ case TOK_FASTCALL3: -+ ad->func_call = FUNC_FASTCALLW; - break; - #endif - case TOK_DLLEXPORT: - ad->dllexport = 1; - break; - default: -- if (tcc_state->warn_unsupported) -- warning("'%s' attribute ignored", get_tok_str(t, NULL)); -+ if (st->warn_unsupported) -+ warning(st, "'%s' attribute ignored", get_tok_str(st, t, NULL)); - /* skip parameters */ -- /* XXX: skip parenthesis too */ - if (tok == '(') { -- next(); -- while (tok != ')' && tok != -1) -- next(); -- next(); -+ int parenthesis = 0; -+ do { -+ if (tok == '(') parenthesis++; -+ else if (tok == ')') parenthesis--; -+ next(st); -+ } while (parenthesis && tok != -1); - } - break; - } - if (tok != ',') - break; -- next(); -+ next(st); - } -- skip(')'); -- skip(')'); -+ skip(st, ')'); -+ skip(st, ')'); - } - } - - /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ --static void struct_decl(CType *type, int u) -+static void struct_decl(TCCState *st, CType *type, int u) - { - int a, v, size, align, maxalign, c, offset; - int bit_size, bit_pos, bsize, bt, lbit_pos; -- Sym *s, *ss, **ps; -+ Sym *s, *ss, *ass, **ps; - AttributeDef ad; - CType type1, btype; - - a = tok; /* save decl type */ -- next(); -+ next(st); - if (tok != '{') { - v = tok; -- next(); -+ next(st); - /* struct already defined ? return it */ - if (v < TOK_IDENT) -- expect("struct/union/enum name"); -- s = struct_find(v); -+ expect(st, "struct/union/enum name"); -+ s = struct_find(st, v); - if (s) { - if (s->type.t != a) -- error("invalid type"); -+ tcc_error(st, "invalid type"); - goto do_decl; - } - } else { -@@ -6465,7 +5699,7 @@ - } - type1.t = a; - /* we put an undefined size for struct/union */ -- s = sym_push(v | SYM_STRUCT, &type1, 0, -1); -+ s = sym_push(st, v | SYM_STRUCT, &type1, 0, -1); - s->r = 0; /* default alignment is zero as gcc */ - /* put struct/union/enum name in type */ - do_decl: -@@ -6473,9 +5707,9 @@ - type->ref = s; - - if (tok == '{') { -- next(); -+ next(st); - if (s->c != -1) -- error("struct/union/enum already defined"); -+ tcc_error(st, "struct/union/enum already defined"); - /* cannot be empty */ - c = 0; - /* non empty enums are not allowed */ -@@ -6483,62 +5717,64 @@ - for(;;) { - v = tok; - if (v < TOK_UIDENT) -- expect("identifier"); -- next(); -+ expect(st, "identifier"); -+ next(st); - if (tok == '=') { -- next(); -- c = expr_const(); -+ next(st); -+ c = expr_const(st); - } - /* enum symbols have static storage */ -- ss = sym_push(v, &int_type, VT_CONST, c); -+ ss = sym_push(st, v, &int_type, VT_CONST, c); - ss->type.t |= VT_STATIC; - if (tok != ',') - break; -- next(); -+ next(st); - c++; - /* NOTE: we accept a trailing comma */ - if (tok == '}') - break; - } -- skip('}'); -+ skip(st, '}'); - } else { - maxalign = 1; - ps = &s->next; - bit_pos = 0; - offset = 0; - while (tok != '}') { -- parse_btype(&btype, &ad); -+ parse_btype(st, &btype, &ad); - while (1) { - bit_size = -1; - v = 0; - type1 = btype; - if (tok != ':') { -- type_decl(&type1, &ad, &v, TYPE_DIRECT); -+ type_decl(st, &type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); -+ if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) -+ expect(st, "identifier"); - if ((type1.t & VT_BTYPE) == VT_FUNC || - (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) -- error("invalid type for '%s'", -- get_tok_str(v, NULL)); -+ tcc_error(st, "invalid type for '%s'", -+ get_tok_str(st, v, NULL)); - } - if (tok == ':') { -- next(); -- bit_size = expr_const(); -+ next(st); -+ bit_size = expr_const(st); - /* XXX: handle v = 0 case for messages */ - if (bit_size < 0) -- error("negative width in bit-field '%s'", -- get_tok_str(v, NULL)); -+ tcc_error(st, "negative width in bit-field '%s'", -+ get_tok_str(st, v, NULL)); - if (v && bit_size == 0) -- error("zero width for bit-field '%s'", -- get_tok_str(v, NULL)); -+ tcc_error(st, "zero width for bit-field '%s'", -+ get_tok_str(st, v, NULL)); - } -- size = type_size(&type1, &align); -+ size = type_size(st, &type1, &align); - if (ad.aligned) { - if (align < ad.aligned) - align = ad.aligned; - } else if (ad.packed) { - align = 1; -- } else if (*tcc_state->pack_stack_ptr) { -- if (align > *tcc_state->pack_stack_ptr) -- align = *tcc_state->pack_stack_ptr; -+ } else if (*st->pack_stack_ptr) { -+ if (align > *st->pack_stack_ptr) -+ align = *st->pack_stack_ptr; - } - lbit_pos = 0; - if (bit_size >= 0) { -@@ -6548,11 +5784,11 @@ - bt != VT_SHORT && - bt != VT_BOOL && - bt != VT_ENUM) -- error("bitfields must have scalar type"); -+ tcc_error(st, "bitfields must have scalar type"); - bsize = size * 8; - if (bit_size > bsize) { -- error("width of '%s' exceeds its type", -- get_tok_str(v, NULL)); -+ tcc_error(st, "width of '%s' exceeds its type", -+ get_tok_str(st, v, NULL)); - } else if (bit_size == bsize) { - /* no need for bit fields */ - bit_pos = 0; -@@ -6576,13 +5812,14 @@ - } else { - bit_pos = 0; - } -- if (v) { -+ if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) { - /* add new memory data only if starting - bit field */ - if (lbit_pos == 0) { - if (a == TOK_STRUCT) { - c = (c + align - 1) & -align; - offset = c; -+ if (size > 0) - c += size; - } else { - offset = 0; -@@ -6594,7 +5831,7 @@ - } - #if 0 - printf("add field %s offset=%d", -- get_tok_str(v, NULL), offset); -+ get_tok_str(st, v, NULL), offset); - if (type1.t & VT_BITFIELD) { - printf(" pos=%d size=%d", - (type1.t >> VT_STRUCT_SHIFT) & 0x3f, -@@ -6602,17 +5839,26 @@ - } - printf("\n"); - #endif -- ss = sym_push(v | SYM_FIELD, &type1, 0, offset); -+ } -+ if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) { -+ ass = type1.ref; -+ while ((ass = ass->next) != NULL) { -+ ss = sym_push(st, ass->v, &ass->type, 0, offset + ass->c); -+ *ps = ss; -+ ps = &ss->next; -+ } -+ } else if (v) { -+ ss = sym_push(st, v | SYM_FIELD, &type1, 0, offset); - *ps = ss; - ps = &ss->next; - } - if (tok == ';' || tok == TOK_EOF) - break; -- skip(','); -+ skip(st, ','); - } -- skip(';'); -+ skip(st, ';'); - } -- skip('}'); -+ skip(st, '}'); - /* store size and alignment */ - s->c = (c + maxalign - 1) & -maxalign; - s->r = maxalign; -@@ -6623,31 +5869,32 @@ - /* return 0 if no type declaration. otherwise, return the basic type - and skip it. - */ --static int parse_btype(CType *type, AttributeDef *ad) -+static int parse_btype(TCCState *st, CType *type, AttributeDef *ad) - { -- int t, u, type_found, typespec_found; -+ int t, u, type_found, typespec_found, typedef_found; - Sym *s; - CType type1; - - memset(ad, 0, sizeof(AttributeDef)); - type_found = 0; - typespec_found = 0; -+ typedef_found = 0; - t = 0; - while(1) { - switch(tok) { - case TOK_EXTENSION: - /* currently, we really ignore extension */ -- next(); -+ next(st); - continue; - - /* basic types */ - case TOK_CHAR: - u = VT_BYTE; - basic_type: -- next(); -+ next(st); - basic_type1: - if ((t & VT_BTYPE) != 0) -- error("too many basic types"); -+ tcc_error(st, "too many basic types"); - t |= u; - typespec_found = 1; - break; -@@ -6658,11 +5905,11 @@ - u = VT_SHORT; - goto basic_type; - case TOK_INT: -- next(); -+ next(st); - typespec_found = 1; - break; - case TOK_LONG: -- next(); -+ next(st); - if ((t & VT_BTYPE) == VT_DOUBLE) { - t = (t & ~VT_BTYPE) | VT_LDOUBLE; - } else if ((t & VT_BTYPE) == VT_LONG) { -@@ -6679,7 +5926,7 @@ - u = VT_FLOAT; - goto basic_type; - case TOK_DOUBLE: -- next(); -+ next(st); - if ((t & VT_BTYPE) == VT_LONG) { - t = (t & ~VT_BTYPE) | VT_LDOUBLE; - } else { -@@ -6688,14 +5935,14 @@ - } - break; - case TOK_ENUM: -- struct_decl(&type1, VT_ENUM); -+ struct_decl(st, &type1, VT_ENUM); - basic_type2: - u = type1.t; - type->ref = type1.ref; - goto basic_type1; - case TOK_STRUCT: - case TOK_UNION: -- struct_decl(&type1, VT_STRUCT); -+ struct_decl(st, &type1, VT_STRUCT); - goto basic_type2; - - /* type modifiers */ -@@ -6703,83 +5950,85 @@ - case TOK_CONST2: - case TOK_CONST3: - t |= VT_CONSTANT; -- next(); -+ next(st); - break; - case TOK_VOLATILE1: - case TOK_VOLATILE2: - case TOK_VOLATILE3: - t |= VT_VOLATILE; -- next(); -+ next(st); - break; - case TOK_SIGNED1: - case TOK_SIGNED2: - case TOK_SIGNED3: - typespec_found = 1; - t |= VT_SIGNED; -- next(); -+ next(st); - break; - case TOK_REGISTER: - case TOK_AUTO: - case TOK_RESTRICT1: - case TOK_RESTRICT2: - case TOK_RESTRICT3: -- next(); -+ next(st); - break; - case TOK_UNSIGNED: - t |= VT_UNSIGNED; -- next(); -+ next(st); - typespec_found = 1; - break; - - /* storage */ - case TOK_EXTERN: - t |= VT_EXTERN; -- next(); -+ next(st); - break; - case TOK_STATIC: - t |= VT_STATIC; -- next(); -+ next(st); - break; - case TOK_TYPEDEF: - t |= VT_TYPEDEF; -- next(); -+ next(st); - break; - case TOK_INLINE1: - case TOK_INLINE2: - case TOK_INLINE3: - t |= VT_INLINE; -- next(); -+ next(st); - break; - - /* GNUC attribute */ - case TOK_ATTRIBUTE1: - case TOK_ATTRIBUTE2: -- parse_attribute(ad); -+ parse_attribute(st, ad); - break; - /* GNUC typeof */ - case TOK_TYPEOF1: - case TOK_TYPEOF2: - case TOK_TYPEOF3: -- next(); -- parse_expr_type(&type1); -+ next(st); -+ parse_expr_type(st, &type1); - goto basic_type2; - default: -- if (typespec_found) -+ if (typespec_found || typedef_found) - goto the_end; -- s = sym_find(tok); -+ s = sym_find(st, tok); - if (!s || !(s->type.t & VT_TYPEDEF)) - goto the_end; -+ typedef_found = 1; - t |= (s->type.t & ~VT_TYPEDEF); - type->ref = s->type.ref; -- next(); -+ next(st); -+ typespec_found = 1; - break; - } - type_found = 1; - } - the_end: - if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED)) -- error("signed and unsigned modifier"); -- if (tcc_state->char_is_unsigned) { -+ tcc_error(st, "signed and unsigned modifier"); -+ if (st->char_is_unsigned) { - if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE) - t |= VT_UNSIGNED; - } -@@ -6794,7 +6043,7 @@ - - /* convert a function parameter type (array to pointer and function to - function pointer) */ --static inline void convert_parameter_type(CType *pt) -+static inline void convert_parameter_type(TCCState *st, CType *pt) - { - /* remove const and volatile qualifiers (XXX: const could be used - to indicate a const function parameter */ -@@ -6802,29 +6051,29 @@ - /* array must be transformed to pointer according to ANSI C */ - pt->t &= ~VT_ARRAY; - if ((pt->t & VT_BTYPE) == VT_FUNC) { -- mk_pointer(pt); -+ mk_pointer(st, pt); - } - } - --static void post_type(CType *type, AttributeDef *ad) -+static void parse_function_parameters(TCCState *st, CType *type, AttributeDef *ad) - { - int n, l, t1; - Sym **plast, *s, *first; - AttributeDef ad1; - CType pt; - -- if (tok == '(') { -- /* function declaration */ -- next(); -+ /* Starting with '(' parse attributes for function declaration */ -+ next(st); - l = 0; - first = NULL; - plast = &first; -- while (tok != ')') { -+ if (tok != ')') { -+ for(;;) { - /* read param name and compute offset */ - if (l != FUNC_OLD) { -- if (!parse_btype(&pt, &ad1)) { -+ if (!parse_btype(st, &pt, &ad1)) { - if (l) { -- error("invalid type"); -+ tcc_error(st, "invalid type"); - } else { - l = FUNC_OLD; - goto old_proto; -@@ -6833,72 +6082,89 @@ - l = FUNC_NEW; - if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') - break; -- type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); -+ type_decl(st, &pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); - if ((pt.t & VT_BTYPE) == VT_VOID) -- error("parameter declared as void"); -+ tcc_error(st, "parameter declared as void"); - } else { - old_proto: - n = tok; -+ if (n < TOK_UIDENT) -+ expect(st, "identifier"); - pt.t = VT_INT; -- next(); -+ next(st); - } -- convert_parameter_type(&pt); -- s = sym_push(n | SYM_FIELD, &pt, 0, 0); -+ convert_parameter_type(st, &pt); -+ s = sym_push(st, n | SYM_FIELD, &pt, 0, 0); - *plast = s; - plast = &s->next; -- if (tok == ',') { -- next(); -+ if (tok == ')') -+ break; -+ skip(st, ','); - if (l == FUNC_NEW && tok == TOK_DOTS) { - l = FUNC_ELLIPSIS; -- next(); -+ next(st); - break; - } - } - } - /* if no parameters, then old type prototype */ -- if (l == 0) -- l = FUNC_OLD; -- skip(')'); -+ if (!l) l = FUNC_OLD; -+ skip(st, ')'); - t1 = type->t & VT_STORAGE; - /* NOTE: const is ignored in returned type as it has a special - meaning in gcc / C++ */ - type->t &= ~(VT_STORAGE | VT_CONSTANT); -- post_type(type, ad); - /* we push a anonymous symbol which will contain the function prototype */ -- s = sym_push(SYM_FIELD, type, ad->func_call, l); -+ s = sym_push(st, SYM_FIELD, type, ad->func_call, l); - s->next = first; - type->t = t1 | VT_FUNC; - type->ref = s; -- } else if (tok == '[') { -- /* array definition */ -- next(); -- n = -1; -+} -+ -+static void parse_array_dimensions(TCCState *st, CType *type) -+{ -+ int n = -1, t1; -+ Sym *s; -+ -+ /* Starting with '[' parse array dimensions */ -+ next(st); -+ if (tok == TOK_RESTRICT1) next(st); - if (tok != ']') { -- n = expr_const(); -- if (n < 0) -- error("invalid array size"); -+ char *message = "invalid array size"; -+ expr_const1(st); -+ /* Conventional constant array? */ -+ if ((vtop->r & (VT_VALMASK |VT_LVAL | VT_SYM)) == VT_CONST) { -+ n = vtop->c.i; -+ vpop(st); -+ -+ if (n < 0)tcc_error(st, message); -+ } else if (!local_stack)tcc_error(st, message); -+ else { -+ gen_assign_cast(st, &int_type); -+ n = -2; -+ tcc_error(st, "dynamic arrays not implemented yet"); -+ } - } -- skip(']'); -+ skip(st, ']'); - /* parse next post type */ - t1 = type->t & VT_STORAGE; - type->t &= ~VT_STORAGE; -- post_type(type, ad); -+ if (tok == '[') parse_array_dimensions(st, type); - - /* we push a anonymous symbol which will contain the array - element type */ -- s = sym_push(SYM_FIELD, type, 0, n); -+ s = sym_push(st, SYM_FIELD, type, 0, n); - type->t = t1 | VT_ARRAY | VT_PTR; - type->ref = s; - } --} - - /* Parse a type declaration (except basic type), and return the type - in 'type'. 'td' is a bitmask indicating which kind of type decl is - expected. 'type' should contain the basic type. 'ad' is the - attribute definition of the basic type. It can be modified by -- type_decl(). -+ type_decl(st). - */ --static void type_decl(CType *type, AttributeDef *ad, int *v, int td) -+static void type_decl(TCCState *st, CType *type, AttributeDef *ad, int *v, int td) - { - Sym *s; - CType type1, *type2; -@@ -6907,7 +6173,7 @@ - while (tok == '*') { - qualifiers = 0; - redo: -- next(); -+ next(st); - switch(tok) { - case TOK_CONST1: - case TOK_CONST2: -@@ -6924,39 +6190,40 @@ - case TOK_RESTRICT3: - goto redo; - } -- mk_pointer(type); -+ mk_pointer(st, type); - type->t |= qualifiers; - } - - /* XXX: clarify attribute handling */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) -- parse_attribute(ad); -+ parse_attribute(st, ad); - - /* recursive type */ -- /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ -+ /* XXX: incorrect if abstract type for functions (e.g. 'int (st)') */ - type1.t = 0; /* XXX: same as int */ - if (tok == '(') { -- next(); -+ next(st); - /* XXX: this is not correct to modify 'ad' at this point, but - the syntax is not clear */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) -- parse_attribute(ad); -- type_decl(&type1, ad, v, td); -- skip(')'); -+ parse_attribute(st, ad); -+ type_decl(st, &type1, ad, v, td); -+ skip(st, ')'); - } else { - /* type identifier */ - if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { - *v = tok; -- next(); -+ next(st); - } else { - if (!(td & TYPE_ABSTRACT)) -- expect("identifier"); -+ expect(st, "identifier"); - *v = 0; - } - } -- post_type(type, ad); -+ if (tok == '(') parse_function_parameters(st, type, ad); -+ else if (tok == '[') parse_array_dimensions(st, type); - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) -- parse_attribute(ad); -+ parse_attribute(st, ad); - if (!type1.t) - return; - /* append type at the end of type1 */ -@@ -6973,7 +6240,7 @@ - } - - /* compute the lvalue VT_LVAL_xxx needed to match type t. */ --static int lvalue_type(int t) -+static int lvalue_type(TCCState *st, int t) - { - int bt, r; - r = VT_LVAL; -@@ -6990,16 +6257,20 @@ - } - - /* indirection with full error checking and bound check */ --static void indir(void) -+static void indir(TCCState *st) - { -- if ((vtop->type.t & VT_BTYPE) != VT_PTR) -- expect("pointer"); -- if ((vtop->r & VT_LVAL) && !nocode_wanted) -- gv(RC_INT); -- vtop->type = *pointed_type(&vtop->type); -- /* an array is never an lvalue */ -- if (!(vtop->type.t & VT_ARRAY)) { -- vtop->r |= lvalue_type(vtop->type.t); -+ if ((vtop->type.t & VT_BTYPE) != VT_PTR) { -+ if ((vtop->type.t & VT_BTYPE) == VT_FUNC) -+ return; -+ expect(st, "pointer"); -+ } -+ if ((vtop->r & VT_LVAL) && cur_text_section) -+ gv(st, RC_INT); -+ vtop->type = *pointed_type(st, &vtop->type); -+ /* Arrays and functions are never lvalues */ -+ if (!(vtop->type.t & VT_ARRAY) -+ && (vtop->type.t & VT_BTYPE) != VT_FUNC) { -+ vtop->r |= lvalue_type(st, vtop->type.t); - /* if bound checking, the referenced pointer must be checked */ - if (do_bounds_check) - vtop->r |= VT_MUSTBOUND; -@@ -7007,7 +6278,7 @@ - } - - /* pass a parameter to a function and do type checking and casting */ --static void gfunc_param_typed(Sym *func, Sym *arg) -+static void gfunc_param_typed(TCCState *st, Sym *func, Sym *arg) - { - int func_type; - CType type; -@@ -7018,52 +6289,52 @@ - /* default casting : only need to convert float to double */ - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) { - type.t = VT_DOUBLE; -- gen_cast(&type); -+ gen_cast(st, &type); - } - } else if (arg == NULL) { -- error("too many arguments to function"); -+ tcc_error(st, "too many arguments to function"); - } else { - type = arg->type; - type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ -- gen_assign_cast(&type); -+ gen_assign_cast(st, &type); - } - } - - /* parse an expression of the form '(type)' or '(expr)' and return its - type */ --static void parse_expr_type(CType *type) -+static void parse_expr_type(TCCState *st, CType *type) - { - int n; - AttributeDef ad; - -- skip('('); -- if (parse_btype(type, &ad)) { -- type_decl(type, &ad, &n, TYPE_ABSTRACT); -+ skip(st, '('); -+ if (parse_btype(st, type, &ad)) { -+ type_decl(st, type, &ad, &n, TYPE_ABSTRACT); - } else { -- expr_type(type); -+ expr_type(st, type); - } -- skip(')'); -+ skip(st, ')'); - } - --static void parse_type(CType *type) -+static void parse_type(TCCState *st, CType *type) - { - AttributeDef ad; - int n; - -- if (!parse_btype(type, &ad)) { -- expect("type"); -+ if (!parse_btype(st, type, &ad)) { -+ expect(st, "type"); - } -- type_decl(type, &ad, &n, TYPE_ABSTRACT); -+ type_decl(st, type, &ad, &n, TYPE_ABSTRACT); - } - --static void vpush_tokc(int t) -+static void vpush_tokc(TCCState *st, int t) - { - CType type; - type.t = t; -- vsetc(&type, VT_CONST, &tokc); -+ vsetc(st, &type, VT_CONST, &tokc); - } - --static void unary(void) -+static void unary(TCCState *st) - { - int n, t, align, size, r; - CType type; -@@ -7075,37 +6346,37 @@ - tok_next: - switch(tok) { - case TOK_EXTENSION: -- next(); -+ next(st); - goto tok_next; - case TOK_CINT: - case TOK_CCHAR: - case TOK_LCHAR: -- vpushi(tokc.i); -- next(); -+ vpushi(st, tokc.i); -+ next(st); - break; - case TOK_CUINT: -- vpush_tokc(VT_INT | VT_UNSIGNED); -- next(); -+ vpush_tokc(st, VT_INT | VT_UNSIGNED); -+ next(st); - break; - case TOK_CLLONG: -- vpush_tokc(VT_LLONG); -- next(); -+ vpush_tokc(st, VT_LLONG); -+ next(st); - break; - case TOK_CULLONG: -- vpush_tokc(VT_LLONG | VT_UNSIGNED); -- next(); -+ vpush_tokc(st, VT_LLONG | VT_UNSIGNED); -+ next(st); - break; - case TOK_CFLOAT: -- vpush_tokc(VT_FLOAT); -- next(); -+ vpush_tokc(st, VT_FLOAT); -+ next(st); - break; - case TOK_CDOUBLE: -- vpush_tokc(VT_DOUBLE); -- next(); -+ vpush_tokc(st, VT_DOUBLE); -+ next(st); - break; - case TOK_CLDOUBLE: -- vpush_tokc(VT_LDOUBLE); -- next(); -+ vpush_tokc(st, VT_LDOUBLE); -+ next(st); - break; - case TOK___FUNCTION__: - if (!gnu_ext) -@@ -7119,36 +6390,40 @@ - len = strlen(funcname) + 1; - /* generate char[len] type */ - type.t = VT_BYTE; -- mk_pointer(&type); -+ mk_pointer(st, &type); - type.t |= VT_ARRAY; - type.ref->c = len; -- vpush_ref(&type, data_section, data_section->data_offset, len); -- ptr = section_ptr_add(data_section, len); -+ vpush_ref(st, &type, data_section, data_section->data_offset, len); -+ ptr = section_ptr_add(st, data_section, len); - memcpy(ptr, funcname, len); -- next(); -+ next(st); - } - break; - case TOK_LSTR: -+#ifdef WIN32 -+ t = VT_SHORT | VT_UNSIGNED; -+#else - t = VT_INT; -+#endif - goto str_init; - case TOK_STR: - /* string parsing */ - t = VT_BYTE; - str_init: -- if (tcc_state->warn_write_strings) -+ if (st->warn_write_strings) - t |= VT_CONSTANT; - type.t = t; -- mk_pointer(&type); -+ mk_pointer(st, &type); - type.t |= VT_ARRAY; - memset(&ad, 0, sizeof(AttributeDef)); -- decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0); -+ decl_initializer_alloc(st, &type, &ad, VT_CONST, 2, 0, 0); - break; - case '(': -- next(); -+ next(st); - /* cast ? */ -- if (parse_btype(&type, &ad)) { -- type_decl(&type, &ad, &n, TYPE_ABSTRACT); -- skip(')'); -+ if (parse_btype(st, &type, &ad)) { -+ type_decl(st, &type, &ad, &n, TYPE_ABSTRACT); -+ skip(st, ')'); - /* check ISOC99 compound literal */ - if (tok == '{') { - /* data is allocated locally by default */ -@@ -7158,170 +6433,174 @@ - r = VT_LOCAL; - /* all except arrays are lvalues */ - if (!(type.t & VT_ARRAY)) -- r |= lvalue_type(type.t); -+ r |= lvalue_type(st, type.t); - memset(&ad, 0, sizeof(AttributeDef)); -- decl_initializer_alloc(&type, &ad, r, 1, 0, 0); -+ decl_initializer_alloc(st, &type, &ad, r, 1, 0, 0); - } else { -- unary(); -- gen_cast(&type); -+ unary(st); -+ gen_cast(st, &type); - } - } else if (tok == '{') { - /* save all registers */ -- save_regs(0); -+ save_regs(st, 0); - /* statement expression : we do not accept break/continue - inside as GCC does */ -- block(NULL, NULL, NULL, NULL, 0, 1); -- skip(')'); -+ block(st, NULL, NULL, NULL, NULL, 0, 1); -+ skip(st, ')'); - } else { -- gexpr(); -- skip(')'); -+ gexpr(st); -+ skip(st, ')'); - } - break; - case '*': -- next(); -- unary(); -- indir(); -+ next(st); -+ unary(st); -+ indir(st); - break; - case '&': -- next(); -- unary(); -+ next(st); -+ unary(st); - /* functions names must be treated as function pointers, - except for unary '&' and sizeof. Since we consider that - functions are not lvalues, we only have to handle it - there and in function calls. */ - /* arrays can also be used although they are not lvalues */ - if ((vtop->type.t & VT_BTYPE) != VT_FUNC && -- !(vtop->type.t & VT_ARRAY)) -- test_lvalue(); -- mk_pointer(&vtop->type); -- gaddrof(); -+ !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL)) -+ test_lvalue(st); -+ mk_pointer(st, &vtop->type); -+ gaddrof(st); - break; - case '!': -- next(); -- unary(); -+ next(st); -+ unary(st); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) - vtop->c.i = !vtop->c.i; - else if ((vtop->r & VT_VALMASK) == VT_CMP) - vtop->c.i = vtop->c.i ^ 1; -- else -- vseti(VT_JMP, gtst(1, 0)); -+ else { -+ save_regs(st, 1); -+ vseti(st, VT_JMP, gtst(st, 1, 0)); -+ } - break; - case '~': -- next(); -- unary(); -- vpushi(-1); -- gen_op('^'); -+ next(st); -+ unary(st); -+ vpushi(st, -1); -+ gen_op(st, '^'); - break; - case '+': -- next(); -+ next(st); - /* in order to force cast, we add zero */ -- unary(); -+ unary(st); - if ((vtop->type.t & VT_BTYPE) == VT_PTR) -- error("pointer not accepted for unary plus"); -- vpushi(0); -- gen_op('+'); -+ tcc_error(st, "pointer not accepted for unary plus"); -+ vpushi(st, 0); -+ gen_op(st, '+'); - break; - case TOK_SIZEOF: - case TOK_ALIGNOF1: - case TOK_ALIGNOF2: - t = tok; -- next(); -+ next(st); - if (tok == '(') { -- parse_expr_type(&type); -+ parse_expr_type(st, &type); - } else { -- unary_type(&type); -+ unary_type(st, &type); - } -- size = type_size(&type, &align); -+ size = type_size(st, &type, &align); - if (t == TOK_SIZEOF) { - if (size < 0) -- error("sizeof applied to an incomplete type"); -- vpushi(size); -+ tcc_error(st, "sizeof applied to an incomplete type"); -+ vpushi(st, size); - } else { -- vpushi(align); -+ vpushi(st, align); - } -+ vtop->type.t |= VT_UNSIGNED; - break; - - case TOK_builtin_types_compatible_p: - { - CType type1, type2; -- next(); -- skip('('); -- parse_type(&type1); -- skip(','); -- parse_type(&type2); -- skip(')'); -+ next(st); -+ skip(st, '('); -+ parse_type(st, &type1); -+ skip(st, ','); -+ parse_type(st, &type2); -+ skip(st, ')'); - type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - type2.t &= ~(VT_CONSTANT | VT_VOLATILE); -- vpushi(is_compatible_types(&type1, &type2)); -+ vpushi(st, is_compatible_types(st, &type1, &type2)); - } - break; - case TOK_builtin_constant_p: - { -- int saved_nocode_wanted, res; -- next(); -- skip('('); -- saved_nocode_wanted = nocode_wanted; -- nocode_wanted = 1; -- gexpr(); -+ Section *saved_text_section; -+ int res; -+ next(st); -+ skip(st, '('); -+ saved_text_section = cur_text_section; -+ cur_text_section = NULL; -+ gexpr(st); - res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; -- vpop(); -- nocode_wanted = saved_nocode_wanted; -- skip(')'); -- vpushi(res); -+ vpop(st); -+ cur_text_section = saved_text_section; -+ skip(st, ')'); -+ vpushi(st, res); - } - break; - case TOK_INC: - case TOK_DEC: - t = tok; -- next(); -- unary(); -- inc(0, t); -+ next(st); -+ unary(st); -+ inc(st, 0, t); - break; - case '-': -- next(); -- vpushi(0); -- unary(); -- gen_op('-'); -+ next(st); -+ vpushi(st, 0); -+ unary(st); -+ gen_op(st, '-'); - break; - case TOK_LAND: - if (!gnu_ext) - goto tok_identifier; -- next(); -+ next(st); - /* allow to take the address of a label */ - if (tok < TOK_UIDENT) -- expect("label identifier"); -- s = label_find(tok); -+ expect(st, "label identifier"); -+ s = label_find(st, tok); - if (!s) { -- s = label_push(&global_label_stack, tok, LABEL_FORWARD); -+ s = label_push(st, &global_label_stack, tok, LABEL_FORWARD); - } else { - if (s->r == LABEL_DECLARED) - s->r = LABEL_FORWARD; - } - if (!s->type.t) { - s->type.t = VT_VOID; -- mk_pointer(&s->type); -+ mk_pointer(st, &s->type); - s->type.t |= VT_STATIC; - } -- vset(&s->type, VT_CONST | VT_SYM, 0); -+ vset(st, &s->type, VT_CONST | VT_SYM, 0); - vtop->sym = s; -- next(); -+ next(st); - break; - default: - tok_identifier: - t = tok; -- next(); -+ next(st); - if (t < TOK_UIDENT) -- expect("identifier"); -- s = sym_find(t); -+ expect(st, "identifier"); -+ s = sym_find(st, t); - if (!s) { - if (tok != '(') -- error("'%s' undeclared", get_tok_str(t, NULL)); -+ tcc_error(st, "'%s' undeclared", get_tok_str(st, t, NULL)); - /* for simple function calls, we tolerate undeclared -- external reference to int() function */ -- if (tcc_state->warn_implicit_function_declaration) -- warning("implicit declaration of function '%s'", -- get_tok_str(t, NULL)); -- s = external_global_sym(t, &func_old_type, 0); -+ external reference to int(st) function */ -+ if (st->warn_implicit_function_declaration) -+ warning(st, "implicit declaration of function '%s'", -+ get_tok_str(st, t, NULL)); -+ s = external_global_sym(st, t, &func_old_type, 0); - } - if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == - (VT_STATIC | VT_INLINE | VT_FUNC)) { -@@ -7331,12 +6610,12 @@ - compilation unit. Inline function as always - generated in the text section. */ - if (!s->c) -- put_extern_sym(s, text_section, 0, 0); -+ put_extern_sym(st, s, text_section, 0, 0); - r = VT_SYM | VT_CONST; - } else { - r = s->r; - } -- vset(&s->type, r, s->c); -+ vset(st, &s->type, r, s->c); - /* if forward reference, we must point to s */ - if (vtop->r & VT_SYM) { - vtop->sym = s; -@@ -7348,18 +6627,18 @@ - /* post operations */ - while (1) { - if (tok == TOK_INC || tok == TOK_DEC) { -- inc(1, tok); -- next(); -+ inc(st, 1, tok); -+ next(st); - } else if (tok == '.' || tok == TOK_ARROW) { - /* field */ - if (tok == TOK_ARROW) -- indir(); -- test_lvalue(); -- gaddrof(); -- next(); -+ indir(st); -+ test_lvalue(st); -+ gaddrof(st); -+ next(st); - /* expect pointer on structure */ - if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) -- expect("struct or union"); -+ expect(st, "struct or union"); - s = vtop->type.ref; - /* find field */ - tok |= SYM_FIELD; -@@ -7368,27 +6647,27 @@ - break; - } - if (!s) -- error("field not found"); -+ tcc_error(st, "field not found"); - /* add field offset to pointer */ - vtop->type = char_pointer_type; /* change type to 'char *' */ -- vpushi(s->c); -- gen_op('+'); -+ vpushi(st, s->c); -+ gen_op(st, '+'); - /* change type to field type, and set to lvalue */ - vtop->type = s->type; - /* an array is never an lvalue */ - if (!(vtop->type.t & VT_ARRAY)) { -- vtop->r |= lvalue_type(vtop->type.t); -+ vtop->r |= lvalue_type(st, vtop->type.t); - /* if bound checking, the referenced pointer must be checked */ - if (do_bounds_check) - vtop->r |= VT_MUSTBOUND; - } -- next(); -+ next(st); - } else if (tok == '[') { -- next(); -- gexpr(); -- gen_op('+'); -- indir(); -- skip(']'); -+ next(st); -+ gexpr(st); -+ gen_op(st, '+'); -+ indir(st); -+ skip(st, ']'); - } else if (tok == '(') { - SValue ret; - Sym *sa; -@@ -7398,38 +6677,38 @@ - if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { - /* pointer test (no array accepted) */ - if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) { -- vtop->type = *pointed_type(&vtop->type); -+ vtop->type = *pointed_type(st, &vtop->type); - if ((vtop->type.t & VT_BTYPE) != VT_FUNC) - goto error_func; - } else { - error_func: -- expect("function pointer"); -+ expect(st, "function pointer"); - } - } else { - vtop->r &= ~VT_LVAL; /* no lvalue */ - } - /* get return type */ - s = vtop->type.ref; -- next(); -+ next(st); - sa = s->next; /* first parameter */ - nb_args = 0; - /* compute first implicit argument if a structure is returned */ - if ((s->type.t & VT_BTYPE) == VT_STRUCT) { - /* get some space for the returned structure */ -- size = type_size(&s->type, &align); -+ size = type_size(st, &s->type, &align); - loc = (loc - size) & -align; - ret.type = s->type; - ret.r = VT_LOCAL | VT_LVAL; - /* pass it as 'int' to avoid structure arg passing - problems */ -- vseti(VT_LOCAL, loc); -+ vseti(st, VT_LOCAL, loc); - ret.c = vtop->c; - nb_args++; - } else { - ret.type = s->type; - ret.r2 = VT_CONST; - /* return in register */ -- if (is_float(ret.type.t)) { -+ if (is_float(st, ret.type.t)) { - ret.r = REG_FRET; - } else { - if ((ret.type.t & VT_BTYPE) == VT_LLONG) -@@ -7440,26 +6719,23 @@ - } - if (tok != ')') { - for(;;) { -- expr_eq(); -- gfunc_param_typed(s, sa); -+ expr_eq(st); -+ gfunc_param_typed(st, s, sa); - nb_args++; - if (sa) - sa = sa->next; - if (tok == ')') - break; -- skip(','); -+ skip(st, ','); - } - } - if (sa) -- error("too few arguments to function"); -- skip(')'); -- if (!nocode_wanted) { -- gfunc_call(nb_args); -- } else { -- vtop -= (nb_args + 1); -- } -+ tcc_error(st, "too few arguments to function"); -+ skip(st, ')'); -+ if (cur_text_section) gfunc_call(st, nb_args); -+ else vtop -= (nb_args + 1); - /* return value */ -- vsetc(&ret.type, ret.r, &ret.c); -+ vsetc(st, &ret.type, ret.r, &ret.c); - vtop->r2 = ret.r2; - } else { - break; -@@ -7467,188 +6743,190 @@ - } - } - --static void uneq(void) -+static void uneq(TCCState *st) - { - int t; - -- unary(); -+ unary(st); - if (tok == '=' || - (tok >= TOK_A_MOD && tok <= TOK_A_DIV) || - tok == TOK_A_XOR || tok == TOK_A_OR || - tok == TOK_A_SHL || tok == TOK_A_SAR) { -- test_lvalue(); -+ test_lvalue(st); - t = tok; -- next(); -+ next(st); - if (t == '=') { -- expr_eq(); -+ expr_eq(st); - } else { -- vdup(); -- expr_eq(); -- gen_op(t & 0x7f); -+ vdup(st); -+ expr_eq(st); -+ gen_op(st, t & 0x7f); - } -- vstore(); -+ vstore(st); - } - } - --static void expr_prod(void) -+static void expr_prod(TCCState *st) - { - int t; - -- uneq(); -+ uneq(st); - while (tok == '*' || tok == '/' || tok == '%') { - t = tok; -- next(); -- uneq(); -- gen_op(t); -+ next(st); -+ uneq(st); -+ gen_op(st, t); - } - } - --static void expr_sum(void) -+static void expr_sum(TCCState *st) - { - int t; - -- expr_prod(); -+ expr_prod(st); - while (tok == '+' || tok == '-') { - t = tok; -- next(); -- expr_prod(); -- gen_op(t); -+ next(st); -+ expr_prod(st); -+ gen_op(st, t); - } - } - --static void expr_shift(void) -+static void expr_shift(TCCState *st) - { - int t; - -- expr_sum(); -+ expr_sum(st); - while (tok == TOK_SHL || tok == TOK_SAR) { - t = tok; -- next(); -- expr_sum(); -- gen_op(t); -+ next(st); -+ expr_sum(st); -+ gen_op(st, t); - } - } - --static void expr_cmp(void) -+static void expr_cmp(TCCState *st) - { - int t; - -- expr_shift(); -+ expr_shift(st); - while ((tok >= TOK_ULE && tok <= TOK_GT) || - tok == TOK_ULT || tok == TOK_UGE) { - t = tok; -- next(); -- expr_shift(); -- gen_op(t); -+ next(st); -+ expr_shift(st); -+ gen_op(st, t); - } - } - --static void expr_cmpeq(void) -+static void expr_cmpeq(TCCState *st) - { - int t; - -- expr_cmp(); -+ expr_cmp(st); - while (tok == TOK_EQ || tok == TOK_NE) { - t = tok; -- next(); -- expr_cmp(); -- gen_op(t); -+ next(st); -+ expr_cmp(st); -+ gen_op(st, t); - } - } - --static void expr_and(void) -+static void expr_and(TCCState *st) - { -- expr_cmpeq(); -+ expr_cmpeq(st); - while (tok == '&') { -- next(); -- expr_cmpeq(); -- gen_op('&'); -+ next(st); -+ expr_cmpeq(st); -+ gen_op(st, '&'); - } - } - --static void expr_xor(void) -+static void expr_xor(TCCState *st) - { -- expr_and(); -+ expr_and(st); - while (tok == '^') { -- next(); -- expr_and(); -- gen_op('^'); -+ next(st); -+ expr_and(st); -+ gen_op(st, '^'); - } - } - --static void expr_or(void) -+static void expr_or(TCCState *st) - { -- expr_xor(); -+ expr_xor(st); - while (tok == '|') { -- next(); -- expr_xor(); -- gen_op('|'); -+ next(st); -+ expr_xor(st); -+ gen_op(st, '|'); - } - } - - /* XXX: fix this mess */ --static void expr_land_const(void) -+static void expr_land_const(TCCState *st) - { -- expr_or(); -+ expr_or(st); - while (tok == TOK_LAND) { -- next(); -- expr_or(); -- gen_op(TOK_LAND); -+ next(st); -+ expr_or(st); -+ gen_op(st, TOK_LAND); - } - } - - /* XXX: fix this mess */ --static void expr_lor_const(void) -+static void expr_lor_const(TCCState *st) - { -- expr_land_const(); -+ expr_land_const(st); - while (tok == TOK_LOR) { -- next(); -- expr_land_const(); -- gen_op(TOK_LOR); -+ next(st); -+ expr_land_const(st); -+ gen_op(st, TOK_LOR); - } - } - - /* only used if non constant */ --static void expr_land(void) -+static void expr_land(TCCState *st) - { - int t; - -- expr_or(); -+ expr_or(st); - if (tok == TOK_LAND) { - t = 0; -+ save_regs(st, 1); - for(;;) { -- t = gtst(1, t); -+ t = gtst(st, 1, t); - if (tok != TOK_LAND) { -- vseti(VT_JMPI, t); -+ vseti(st, VT_JMPI, t); - break; - } -- next(); -- expr_or(); -+ next(st); -+ expr_or(st); - } - } - } - --static void expr_lor(void) -+static void expr_lor(TCCState *st) - { - int t; - -- expr_land(); -+ expr_land(st); - if (tok == TOK_LOR) { - t = 0; -+ save_regs(st, 1); - for(;;) { -- t = gtst(0, t); -+ t = gtst(st, 0, t); - if (tok != TOK_LOR) { -- vseti(VT_JMP, t); -+ vseti(st, VT_JMP, t); - break; - } -- next(); -- expr_land(); -+ next(st); -+ expr_land(st); - } - } - } - - /* XXX: better constant handling */ --static void expr_eq(void) -+static void expr_eq(TCCState *st) - { - int tt, u, r1, r2, rc, t1, t2, bt1, bt2; - SValue sv; -@@ -7656,51 +6934,51 @@ - - if (const_wanted) { - int c1, c; -- expr_lor_const(); -+ expr_lor_const(st); - if (tok == '?') { - c = vtop->c.i; -- vpop(); -- next(); -+ vpop(st); -+ next(st); - if (tok == ':' && gnu_ext) { - c1 = c; - } else { -- gexpr(); -+ gexpr(st); - c1 = vtop->c.i; -- vpop(); -+ vpop(st); - } -- skip(':'); -- expr_eq(); -+ skip(st, ':'); -+ expr_eq(st); - if (c) - vtop->c.i = c1; - } - } else { -- expr_lor(); -+ expr_lor(st); - if (tok == '?') { -- next(); -+ next(st); - if (vtop != vstack) { - /* needed to avoid having different registers saved in - each branch */ -- if (is_float(vtop->type.t)) -+ if (is_float(st, vtop->type.t)) - rc = RC_FLOAT; - else - rc = RC_INT; -- gv(rc); -- save_regs(1); -+ gv(st, rc); -+ save_regs(st, 1); - } - if (tok == ':' && gnu_ext) { -- gv_dup(); -- tt = gtst(1, 0); -+ gv_dup(st); -+ tt = gtst(st, 1, 0); - } else { -- tt = gtst(1, 0); -- gexpr(); -+ tt = gtst(st, 1, 0); -+ gexpr(st); - } - type1 = vtop->type; - sv = *vtop; /* save value to handle it later */ - vtop--; /* no vpop so that FP stack is not flushed */ -- skip(':'); -- u = gjmp(0); -+ skip(st, ':'); -+ u = gjmp(st, 0); - gsym(tt); -- expr_eq(); -+ expr_eq(st); - type2 = vtop->type; - - t1 = type1.t; -@@ -7708,7 +6986,7 @@ - t2 = type2.t; - bt2 = t2 & VT_BTYPE; - /* cast operands to correct type according to ISOC rules */ -- if (is_float(bt1) || is_float(bt2)) { -+ if (is_float(st, bt1) || is_float(st, bt2)) { - if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { - type.t = VT_LDOUBLE; - } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { -@@ -7726,6 +7004,9 @@ - } else if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* XXX: test pointer compatibility */ - type = type1; -+ } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { -+ /* XXX: test function pointer compatibility */ -+ type = type1; - } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { - /* XXX: test structure compatibility */ - type = type1; -@@ -7742,9 +7023,11 @@ - } - - /* now we convert second operand */ -- gen_cast(&type); -+ gen_cast(st, &type); -+ if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) -+ gaddrof(st); - rc = RC_INT; -- if (is_float(type.t)) { -+ if (is_float(st, type.t)) { - rc = RC_FLOAT; - } else if ((type.t & VT_BTYPE) == VT_LLONG) { - /* for long longs, we use fixed registers to avoid having -@@ -7752,85 +7035,85 @@ - rc = RC_IRET; - } - -- r2 = gv(rc); -+ r2 = gv(st, rc); - /* this is horrible, but we must also convert first - operand */ -- tt = gjmp(0); -+ tt = gjmp(st, 0); - gsym(u); - /* put again first value and cast it */ - *vtop = sv; -- gen_cast(&type); -- r1 = gv(rc); -- move_reg(r2, r1); -+ gen_cast(st, &type); -+ if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) -+ gaddrof(st); -+ r1 = gv(st, rc); -+ move_reg(st, r2, r1); - vtop->r = r2; - gsym(tt); - } - } - } - --static void gexpr(void) -+static void gexpr(TCCState *st) - { - while (1) { -- expr_eq(); -+ expr_eq(st); - if (tok != ',') - break; -- vpop(); -- next(); -+ vpop(st); -+ next(st); - } - } - - /* parse an expression and return its type without any side effect. */ --static void expr_type(CType *type) -+static void expr_type(TCCState *st, CType *type) - { -- int saved_nocode_wanted; -+ Section *saved_text_section = cur_text_section; - -- saved_nocode_wanted = nocode_wanted; -- nocode_wanted = 1; -- gexpr(); -+ cur_text_section = NULL; -+ gexpr(st); - *type = vtop->type; -- vpop(); -- nocode_wanted = saved_nocode_wanted; -+ vpop(st); -+ cur_text_section = saved_text_section; - } - - /* parse a unary expression and return its type without any side - effect. */ --static void unary_type(CType *type) -+static void unary_type(TCCState *st, CType *type) - { -- int a; -+ Section *saved_text_section = cur_text_section; - -- a = nocode_wanted; -- nocode_wanted = 1; -- unary(); -+ cur_text_section = NULL; -+ unary(st); - *type = vtop->type; -- vpop(); -- nocode_wanted = a; -+ vpop(st); -+ cur_text_section = saved_text_section; - } - - /* parse a constant expression and return value in vtop. */ --static void expr_const1(void) -+static void expr_const1(TCCState *st) - { - int a; - a = const_wanted; - const_wanted = 1; -- expr_eq(); -+ expr_eq(st); - const_wanted = a; - } - - /* parse an integer constant and return its value. */ --static int expr_const(void) -+static int expr_const(TCCState *st) - { - int c; -- expr_const1(); -+ expr_const1(st); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) -- expect("constant expression"); -+ expect(st, "constant expression"); - c = vtop->c.i; -- vpop(); -+ vpop(st); - return c; - } - - /* return the label token if current token is a label, otherwise - return zero */ --static int is_label(void) -+static int is_label(TCCState *st) - { - int last_tok; - -@@ -7839,17 +7122,17 @@ - return 0; - /* no need to save tokc because tok is an identifier */ - last_tok = tok; -- next(); -+ next(st); - if (tok == ':') { -- next(); -+ next(st); - return last_tok; - } else { -- unget_tok(last_tok); -+ unget_tok(st, last_tok); - return 0; - } - } - --static void block(int *bsym, int *csym, int *case_sym, int *def_sym, -+static void block(TCCState *st, int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr) - { - int a, b, c, d; -@@ -7858,181 +7141,204 @@ - /* generate line number info */ - if (do_debug && - (last_line_num != file->line_num || last_ind != ind)) { -- put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); -+ put_stabn(st, N_SLINE, 0, file->line_num, ind - func_ind); - last_ind = ind; - last_line_num = file->line_num; - } - - if (is_expr) { - /* default return value is (void) */ -- vpushi(0); -+ vpushi(st, 0); - vtop->type.t = VT_VOID; - } - - if (tok == TOK_IF) { - /* if test */ -- next(); -- skip('('); -- gexpr(); -- skip(')'); -- a = gtst(1, 0); -- block(bsym, csym, case_sym, def_sym, case_reg, 0); -+ next(st); -+ skip(st, '('); -+ gexpr(st); -+ skip(st, ')'); -+ a = gtst(st, 1, 0); -+ block(st, bsym, csym, case_sym, def_sym, case_reg, 0); - c = tok; - if (c == TOK_ELSE) { -- next(); -- d = gjmp(0); -+ next(st); -+ d = gjmp(st, 0); - gsym(a); -- block(bsym, csym, case_sym, def_sym, case_reg, 0); -+ block(st, bsym, csym, case_sym, def_sym, case_reg, 0); - gsym(d); /* patch else jmp */ - } else - gsym(a); - } else if (tok == TOK_WHILE) { -- next(); -+ next(st); - d = ind; -- skip('('); -- gexpr(); -- skip(')'); -- a = gtst(1, 0); -+ skip(st, '('); -+ gexpr(st); -+ skip(st, ')'); -+ a = gtst(st, 1, 0); - b = 0; -- block(&a, &b, case_sym, def_sym, case_reg, 0); -- gjmp_addr(d); -+ block(st, &a, &b, case_sym, def_sym, case_reg, 0); -+ gjmp_addr(st, d); - gsym(a); - gsym_addr(b, d); - } else if (tok == '{') { - Sym *llabel; - -- next(); -+ next(st); - /* record local declaration stack position */ - s = local_stack; - llabel = local_label_stack; - /* handle local labels declarations */ - if (tok == TOK_LABEL) { -- next(); -+ next(st); - for(;;) { - if (tok < TOK_UIDENT) -- expect("label identifier"); -- label_push(&local_label_stack, tok, LABEL_DECLARED); -- next(); -+ expect(st, "label identifier"); -+ label_push(st, &local_label_stack, tok, LABEL_DECLARED); -+ next(st); - if (tok == ',') { -- next(); -+ next(st); - } else { -- skip(';'); -+ skip(st, ';'); - break; - } - } - } - while (tok != '}') { -- decl(VT_LOCAL); -+ decl(st, VT_LOCAL); - if (tok != '}') { - if (is_expr) -- vpop(); -- block(bsym, csym, case_sym, def_sym, case_reg, is_expr); -+ vpop(st); -+ block(st, bsym, csym, case_sym, def_sym, case_reg, is_expr); - } - } - /* pop locally defined labels */ -- label_pop(&local_label_stack, llabel); -+ label_pop(st, &local_label_stack, llabel); - /* pop locally defined symbols */ -- sym_pop(&local_stack, s); -- next(); -+ sym_pop(st, &local_stack, s); -+ next(st); - } else if (tok == TOK_RETURN) { -- next(); -+ next(st); - if (tok != ';') { -- gexpr(); -- gen_assign_cast(&func_vt); -+ gexpr(st); -+ gen_assign_cast(st, &func_vt); - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - CType type; - /* if returning structure, must copy it to implicit - first pointer arg location */ -+#ifdef TCC_ARM_EABI -+ int align, size; -+ size = type_size(st, &func_vt,&align); -+ if(size <= 4) { -+ if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3)) -+ && (align & 3)) -+ { -+ int addr; -+ loc = (loc - size) & -4; -+ addr = loc; - type = func_vt; -- mk_pointer(&type); -- vset(&type, VT_LOCAL | VT_LVAL, func_vc); -- indir(); -- vswap(); -- /* copy structure value to pointer */ -- vstore(); -- } else if (is_float(func_vt.t)) { -- gv(RC_FRET); -+ vset(st, &type, VT_LOCAL | VT_LVAL, addr); -+ vswap(st); -+ vstore(st); -+ vset(st, &int_type, VT_LOCAL | VT_LVAL, addr); -+ } -+ vtop->type = int_type; -+ gv(st, RC_IRET); - } else { -- gv(RC_IRET); -+#endif -+ type = func_vt; -+ mk_pointer(st, &type); -+ vset(st, &type, VT_LOCAL | VT_LVAL, func_vc); -+ indir(st); -+ vswap(st); -+ /* copy structure value to pointer */ -+ vstore(st); -+#ifdef TCC_ARM_EABI - } -- vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ -+#endif -+ } else if (is_float(st, func_vt.t)) { -+ gv(st, RC_FRET); -+ } else { -+ gv(st, RC_IRET); -+ } -+ vtop--; /* NOT vpop(st) because on x86 it would flush the fp stack */ - } -- skip(';'); -- rsym = gjmp(rsym); /* jmp */ -+ skip(st, ';'); -+ rsym = gjmp(st, rsym); /* jmp */ - } else if (tok == TOK_BREAK) { - /* compute jump */ - if (!bsym) -- error("cannot break"); -- *bsym = gjmp(*bsym); -- next(); -- skip(';'); -+ tcc_error(st, "cannot break"); -+ *bsym = gjmp(st, *bsym); -+ next(st); -+ skip(st, ';'); - } else if (tok == TOK_CONTINUE) { - /* compute jump */ - if (!csym) -- error("cannot continue"); -- *csym = gjmp(*csym); -- next(); -- skip(';'); -+ tcc_error(st, "cannot continue"); -+ *csym = gjmp(st, *csym); -+ next(st); -+ skip(st, ';'); - } else if (tok == TOK_FOR) { - int e; -- next(); -- skip('('); -+ next(st); -+ skip(st, '('); - if (tok != ';') { -- gexpr(); -- vpop(); -+ gexpr(st); -+ vpop(st); - } -- skip(';'); -+ skip(st, ';'); - d = ind; - c = ind; - a = 0; - b = 0; - if (tok != ';') { -- gexpr(); -- a = gtst(1, 0); -+ gexpr(st); -+ a = gtst(st, 1, 0); - } -- skip(';'); -+ skip(st, ';'); - if (tok != ')') { -- e = gjmp(0); -+ e = gjmp(st, 0); - c = ind; -- gexpr(); -- vpop(); -- gjmp_addr(d); -+ gexpr(st); -+ vpop(st); -+ gjmp_addr(st, d); - gsym(e); - } -- skip(')'); -- block(&a, &b, case_sym, def_sym, case_reg, 0); -- gjmp_addr(c); -+ skip(st, ')'); -+ block(st, &a, &b, case_sym, def_sym, case_reg, 0); -+ gjmp_addr(st, c); - gsym(a); - gsym_addr(b, c); - } else - if (tok == TOK_DO) { -- next(); -+ next(st); - a = 0; - b = 0; - d = ind; -- block(&a, &b, case_sym, def_sym, case_reg, 0); -- skip(TOK_WHILE); -- skip('('); -+ block(st, &a, &b, case_sym, def_sym, case_reg, 0); -+ skip(st, TOK_WHILE); -+ skip(st, '('); - gsym(b); -- gexpr(); -- c = gtst(0, 0); -+ gexpr(st); -+ c = gtst(st, 0, 0); - gsym_addr(c, d); -- skip(')'); -+ skip(st, ')'); - gsym(a); -- skip(';'); -+ skip(st, ';'); - } else - if (tok == TOK_SWITCH) { -- next(); -- skip('('); -- gexpr(); -+ next(st); -+ skip(st, '('); -+ gexpr(st); - /* XXX: other types than integer */ -- case_reg = gv(RC_INT); -- vpop(); -- skip(')'); -+ case_reg = gv(st, RC_INT); -+ vpop(st); -+ skip(st, ')'); - a = 0; -- b = gjmp(0); /* jump to first case */ -+ b = gjmp(st, 0); /* jump to first case */ - c = 0; -- block(&a, csym, &b, &c, case_reg, 0); -+ block(st, &a, csym, &b, &c, case_reg, 0); - /* if no default, jmp after switch */ - if (c == 0) - c = ind; -@@ -8044,113 +7350,118 @@ - if (tok == TOK_CASE) { - int v1, v2; - if (!case_sym) -- expect("switch"); -- next(); -- v1 = expr_const(); -+ expect(st, "switch"); -+ /* since a case is like a label, we must skip it with a jmp */ -+ b = gjmp(st, 0); -+ next_case: -+ next(st); -+ v1 = expr_const(st); - v2 = v1; - if (gnu_ext && tok == TOK_DOTS) { -- next(); -- v2 = expr_const(); -+ next(st); -+ v2 = expr_const(st); - if (v2 < v1) -- warning("empty case range"); -+ warning(st, "empty case range"); - } -- /* since a case is like a label, we must skip it with a jmp */ -- b = gjmp(0); - gsym(*case_sym); -- vseti(case_reg, 0); -- vpushi(v1); -+ vseti(st, case_reg, 0); -+ vpushi(st, v1); - if (v1 == v2) { -- gen_op(TOK_EQ); -- *case_sym = gtst(1, 0); -+ gen_op(st, TOK_EQ); -+ *case_sym = 0; - } else { -- gen_op(TOK_GE); -- *case_sym = gtst(1, 0); -- vseti(case_reg, 0); -- vpushi(v2); -- gen_op(TOK_LE); -- *case_sym = gtst(1, *case_sym); -+ gen_op(st, TOK_GE); -+ *case_sym = gtst(st, 1, 0); -+ vseti(st, case_reg, 0); -+ vpushi(st, v2); -+ gen_op(st, TOK_LE); - } -+ skip(st, ':'); -+ if (tok == TOK_CASE) { -+ b = gtst(st, 0, b); -+ goto next_case; -+ } -+ *case_sym = gtst(st, 1, *case_sym); - gsym(b); -- skip(':'); - is_expr = 0; - goto block_after_label; - } else - if (tok == TOK_DEFAULT) { -- next(); -- skip(':'); -+ next(st); -+ skip(st, ':'); - if (!def_sym) -- expect("switch"); -+ expect(st, "switch"); - if (*def_sym) -- error("too many 'default'"); -+ tcc_error(st, "too many 'default'"); - *def_sym = ind; - is_expr = 0; - goto block_after_label; - } else - if (tok == TOK_GOTO) { -- next(); -+ next(st); - if (tok == '*' && gnu_ext) { - /* computed goto */ -- next(); -- gexpr(); -+ next(st); -+ gexpr(st); - if ((vtop->type.t & VT_BTYPE) != VT_PTR) -- expect("pointer"); -- ggoto(); -+ expect(st, "pointer"); -+ ggoto(st); - } else if (tok >= TOK_UIDENT) { -- s = label_find(tok); -+ s = label_find(st, tok); - /* put forward definition if needed */ - if (!s) { -- s = label_push(&global_label_stack, tok, LABEL_FORWARD); -+ s = label_push(st, &global_label_stack, tok, LABEL_FORWARD); - } else { - if (s->r == LABEL_DECLARED) - s->r = LABEL_FORWARD; - } - /* label already defined */ - if (s->r & LABEL_FORWARD) -- s->next = (void *)gjmp((long)s->next); -+ s->next = (void *)gjmp(st, (long)s->next); - else -- gjmp_addr((long)s->next); -- next(); -+ gjmp_addr(st, (long)s->next); -+ next(st); - } else { -- expect("label identifier"); -+ expect(st, "label identifier"); - } -- skip(';'); -+ skip(st, ';'); - } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { -- asm_instr(); -+ asm_instr(st); - } else { -- b = is_label(); -+ b = is_label(st); - if (b) { - /* label case */ -- s = label_find(b); -+ s = label_find(st, b); - if (s) { - if (s->r == LABEL_DEFINED) -- error("duplicate label '%s'", get_tok_str(s->v, NULL)); -+ tcc_error(st, "duplicate label '%s'", get_tok_str(st, s->v, NULL)); - gsym((long)s->next); - s->r = LABEL_DEFINED; - } else { -- s = label_push(&global_label_stack, b, LABEL_DEFINED); -+ s = label_push(st, &global_label_stack, b, LABEL_DEFINED); - } - s->next = (void *)ind; - /* we accept this, but it is a mistake */ - block_after_label: - if (tok == '}') { -- warning("deprecated use of label at end of compound statement"); -+ warning(st, "deprecated use of label at end of compound statement"); - } else { - if (is_expr) -- vpop(); -- block(bsym, csym, case_sym, def_sym, case_reg, is_expr); -+ vpop(st); -+ block(st, bsym, csym, case_sym, def_sym, case_reg, is_expr); - } - } else { - /* expression case */ - if (tok != ';') { - if (is_expr) { -- vpop(); -- gexpr(); -+ vpop(st); -+ gexpr(st); - } else { -- gexpr(); -- vpop(); -+ gexpr(st); -+ vpop(st); - } - } -- skip(';'); -+ skip(st, ';'); - } - } - } -@@ -8159,7 +7470,7 @@ - address. cur_index/cur_field is the pointer to the current - value. 'size_only' is true if only size info is needed (only used - in arrays) */ --static void decl_designator(CType *type, Section *sec, unsigned long c, -+static void decl_designator(TCCState *st, CType *type, Section *sec, unsigned long c, - int *cur_index, Sym **cur_field, - int size_only) - { -@@ -8170,32 +7481,32 @@ - notfirst = 0; - elem_size = 0; - nb_elems = 1; -- if (gnu_ext && (l = is_label()) != 0) -+ if (gnu_ext && (l = is_label(st)) != 0) - goto struct_field; - while (tok == '[' || tok == '.') { - if (tok == '[') { - if (!(type->t & VT_ARRAY)) -- expect("array type"); -+ expect(st, "array type"); - s = type->ref; -- next(); -- index = expr_const(); -+ next(st); -+ index = expr_const(st); - if (index < 0 || (s->c >= 0 && index >= s->c)) -- expect("invalid index"); -+ expect(st, "invalid index"); - if (tok == TOK_DOTS && gnu_ext) { -- next(); -- index_last = expr_const(); -+ next(st); -+ index_last = expr_const(st); - if (index_last < 0 || - (s->c >= 0 && index_last >= s->c) || - index_last < index) -- expect("invalid index"); -+ expect(st, "invalid index"); - } else { - index_last = index; - } -- skip(']'); -+ skip(st, ']'); - if (!notfirst) - *cur_index = index_last; -- type = pointed_type(type); -- elem_size = type_size(type, &align); -+ type = pointed_type(st, type); -+ elem_size = type_size(st, type, &align); - c += index * elem_size; - /* NOTE: we only support ranges for last designator */ - nb_elems = index_last - index + 1; -@@ -8204,12 +7515,12 @@ - break; - } - } else { -- next(); -+ next(st); - l = tok; -- next(); -+ next(st); - struct_field: - if ((type->t & VT_BTYPE) != VT_STRUCT) -- expect("struct/union type"); -+ expect(st, "struct/union type"); - s = type->ref; - l |= SYM_FIELD; - f = s->next; -@@ -8219,7 +7530,7 @@ - f = f->next; - } - if (!f) -- expect("field"); -+ expect(st, "field"); - if (!notfirst) - *cur_field = f; - /* XXX: fix this mess by using explicit storage field */ -@@ -8232,20 +7543,20 @@ - } - if (notfirst) { - if (tok == '=') { -- next(); -+ next(st); - } else { - if (!gnu_ext) -- expect("="); -+ expect(st, "="); - } - } else { - if (type->t & VT_ARRAY) { - index = *cur_index; -- type = pointed_type(type); -- c += index * type_size(type, &align); -+ type = pointed_type(st, type); -+ c += index * type_size(st, type, &align); - } else { - f = *cur_field; - if (!f) -- error("too many field init"); -+ tcc_error(st, "too many field init"); - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); -@@ -8253,7 +7564,7 @@ - c += f->c; - } - } -- decl_initializer(type, sec, c, 0, size_only); -+ decl_initializer(st, type, sec, c, 0, size_only); - - /* XXX: make it more general */ - if (!size_only && nb_elems > 1) { -@@ -8262,10 +7573,10 @@ - int i; - - if (!sec) -- error("range init not supported yet for dynamic storage"); -+ tcc_error(st, "range init not supported yet for dynamic storage"); - c_end = c + nb_elems * elem_size; - if (c_end > sec->data_allocated) -- section_realloc(sec, c_end); -+ section_realloc(st, sec, c_end); - src = sec->data + c; - dst = src; - for(i = 1; i < nb_elems; i++) { -@@ -8280,7 +7591,7 @@ - #define EXPR_ANY 2 - - /* store a value or an expression directly in global data or in local array */ --static void init_putv(CType *type, Section *sec, unsigned long c, -+static void init_putv(TCCState *st, CType *type, Section *sec, unsigned long c, - int v, int expr_type) - { - int saved_global_expr, bt, bit_pos, bit_size; -@@ -8290,20 +7601,20 @@ - - switch(expr_type) { - case EXPR_VAL: -- vpushi(v); -+ vpushi(st, v); - break; - case EXPR_CONST: - /* compound literals must be allocated globally in this case */ - saved_global_expr = global_expr; - global_expr = 1; -- expr_const1(); -+ expr_const1(st); - global_expr = saved_global_expr; - /* NOTE: symbols are accepted */ - if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) -- error("initializer element is not constant"); -+ tcc_error(st, "initializer element is not constant"); - break; - case EXPR_ANY: -- expr_eq(); -+ expr_eq(st); - break; - } - -@@ -8313,7 +7624,7 @@ - if (sec) { - /* XXX: not portable */ - /* XXX: generate error if incorrect relocation */ -- gen_assign_cast(&dtype); -+ gen_assign_cast(st, &dtype); - bt = type->t & VT_BTYPE; - ptr = sec->data + c; - /* XXX: make code faster ? */ -@@ -8333,7 +7644,7 @@ - bt == VT_LDOUBLE || - bt == VT_LLONG || - (bt == VT_INT && bit_size != 32))) -- error("initializer element is not computable at load time"); -+ tcc_error(st, "initializer element is not computable at load time"); - switch(bt) { - case VT_BYTE: - *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; -@@ -8352,31 +7663,31 @@ - break; - default: - if (vtop->r & VT_SYM) { -- greloc(sec, vtop->sym, c, R_DATA_32); -+ greloc(st, sec, vtop->sym, c, R_DATA_32); - } - *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - } - vtop--; - } else { -- vset(&dtype, VT_LOCAL, c); -- vswap(); -- vstore(); -- vpop(); -+ vset(st, &dtype, VT_LOCAL|VT_LVAL, c); -+ vswap(st); -+ vstore(st); -+ vpop(st); - } - } - - /* put zeros for variable based init */ --static void init_putz(CType *t, Section *sec, unsigned long c, int size) -+static void init_putz(TCCState *st, CType *t, Section *sec, unsigned long c, int size) - { - if (sec) { - /* nothing to do because globals are already set to zero */ - } else { -- vpush_global_sym(&func_old_type, TOK_memset); -- vseti(VT_LOCAL, c); -- vpushi(0); -- vpushi(size); -- gfunc_call(3); -+ vpush_global_sym(st, &func_old_type, TOK_memset); -+ vseti(st, VT_LOCAL, c); -+ vpushi(st, 0); -+ vpushi(st, size); -+ gfunc_call(st, 3); - } - } - -@@ -8385,7 +7696,7 @@ - allocation. 'first' is true if array '{' must be read (multi - dimension implicit array init handling). 'size_only' is true if - size only evaluation is wanted (only for arrays). */ --static void decl_initializer(CType *type, Section *sec, unsigned long c, -+static void decl_initializer(TCCState *st, CType *type, Section *sec, unsigned long c, - int first, int size_only) - { - int index, array_length, n, no_oblock, nb, parlevel, i; -@@ -8397,20 +7708,24 @@ - s = type->ref; - n = s->c; - array_length = 0; -- t1 = pointed_type(type); -- size1 = type_size(t1, &align1); -+ t1 = pointed_type(st, type); -+ size1 = type_size(st, t1, &align1); - - no_oblock = 1; - if ((first && tok != TOK_LSTR && tok != TOK_STR) || - tok == '{') { -- skip('{'); -+ skip(st, '{'); - no_oblock = 0; - } - - /* only parse strings here if correct type (otherwise: handle - them as ((w)char *) expressions */ - if ((tok == TOK_LSTR && -+#ifdef WIN32 -+ (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)) || -+#else - (t1->t & VT_BTYPE) == VT_INT) || -+#endif - (tok == TOK_STR && - (t1->t & VT_BTYPE) == VT_BYTE)) { - while (tok == TOK_STR || tok == TOK_LSTR) { -@@ -8422,14 +7737,14 @@ - if (tok == TOK_STR) - cstr_len = cstr->size; - else -- cstr_len = cstr->size / sizeof(int); -+ cstr_len = cstr->size / sizeof(nwchar_t); - cstr_len--; - nb = cstr_len; - if (n >= 0 && nb > (n - array_length)) - nb = n - array_length; - if (!size_only) { - if (cstr_len > nb) -- warning("initializer-string for array is too long"); -+ warning(st, "initializer-string for array is too long"); - /* in order to go faster for common case (char - string in global variable, we handle it - specifically */ -@@ -8440,33 +7755,33 @@ - if (tok == TOK_STR) - ch = ((unsigned char *)cstr->data)[i]; - else -- ch = ((int *)cstr->data)[i]; -- init_putv(t1, sec, c + (array_length + i) * size1, -+ ch = ((nwchar_t *)cstr->data)[i]; -+ init_putv(st, t1, sec, c + (array_length + i) * size1, - ch, EXPR_VAL); - } - } - } - array_length += nb; -- next(); -+ next(st); - } - /* only add trailing zero if enough storage (no - warning in this case since it is standard) */ - if (n < 0 || array_length < n) { - if (!size_only) { -- init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); -+ init_putv(st, t1, sec, c + (array_length * size1), 0, EXPR_VAL); - } - array_length++; - } - } else { - index = 0; - while (tok != '}') { -- decl_designator(type, sec, c, &index, NULL, size_only); -+ decl_designator(st, type, sec, c, &index, NULL, size_only); - if (n >= 0 && index >= n) -- error("index too large"); -+ tcc_error(st, "index too large"); - /* must put zero in holes (note that doing it that way - ensures that it even works with designators) */ - if (!size_only && array_length < index) { -- init_putz(t1, sec, c + array_length * size1, -+ init_putz(st, t1, sec, c + array_length * size1, - (index - array_length) * size1); - } - index++; -@@ -8479,14 +7794,14 @@ - break; - if (tok == '}') - break; -- skip(','); -+ skip(st, ','); - } - } - if (!no_oblock) -- skip('}'); -+ skip(st, '}'); - /* put zeros at the end */ - if (!size_only && n >= 0 && array_length < n) { -- init_putz(t1, sec, c + array_length * size1, -+ init_putz(st, t1, sec, c + array_length * size1, - (n - array_length) * size1); - } - /* patch type size if needed */ -@@ -8508,23 +7823,23 @@ - if (tok == '(') { - AttributeDef ad1; - CType type1; -- next(); -+ next(st); - while (tok == '(') { - par_count++; -- next(); -+ next(st); - } -- if (!parse_btype(&type1, &ad1)) -- expect("cast"); -- type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); -+ if (!parse_btype(st, &type1, &ad1)) -+ expect(st, "cast"); -+ type_decl(st, &type1, &ad1, &n, TYPE_ABSTRACT); - #if 0 - if (!is_assignable_types(type, &type1)) -- error("invalid type for cast"); -+ tcc_error(st, "invalid type for cast"); - #endif -- skip(')'); -+ skip(st, ')'); - } - no_oblock = 1; - if (first || tok == '{') { -- skip('{'); -+ skip(st, '{'); - no_oblock = 0; - } - s = type->ref; -@@ -8533,13 +7848,13 @@ - index = 0; - n = s->c; - while (tok != '}') { -- decl_designator(type, sec, c, NULL, &f, size_only); -+ decl_designator(st, type, sec, c, NULL, &f, size_only); - index = f->c; - if (!size_only && array_length < index) { -- init_putz(type, sec, c + array_length, -+ init_putz(st, type, sec, c + array_length, - index - array_length); - } -- index = index + type_size(&f->type, &align1); -+ index = index + type_size(st, &f->type, &align1); - if (index > array_length) - array_length = index; - f = f->next; -@@ -8547,23 +7862,23 @@ - break; - if (tok == '}') - break; -- skip(','); -+ skip(st, ','); - } - /* put zeros at the end */ - if (!size_only && array_length < n) { -- init_putz(type, sec, c + array_length, -+ init_putz(st, type, sec, c + array_length, - n - array_length); - } - if (!no_oblock) -- skip('}'); -+ skip(st, '}'); - while (par_count) { -- skip(')'); -+ skip(st, ')'); - par_count--; - } - } else if (tok == '{') { -- next(); -- decl_initializer(type, sec, c, first, size_only); -- skip('}'); -+ next(st); -+ decl_initializer(st, type, sec, c, first, size_only); -+ skip(st, '}'); - } else if (size_only) { - /* just skip expression */ - parlevel = 0; -@@ -8573,7 +7888,7 @@ - parlevel++; - else if (tok == ')') - parlevel--; -- next(); -+ next(st); - } - } else { - /* currently, we always use constant expression for globals -@@ -8581,7 +7896,7 @@ - expr_type = EXPR_CONST; - if (!sec) - expr_type = EXPR_ANY; -- init_putv(type, sec, c, 0, expr_type); -+ init_putv(st, type, sec, c, 0, expr_type); - } - } - -@@ -8592,7 +7907,7 @@ - parsed. If 'v' is zero, then a reference to the new object is put - in the value stack. If 'has_init' is 2, a special parsing is done - to handle string constants. */ --static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, -+static void decl_initializer_alloc(TCCState *st, CType *type, AttributeDef *ad, int r, - int has_init, int v, int scope) - { - int size, align, addr, data_offset; -@@ -8601,30 +7916,30 @@ - TokenString init_str; - Section *sec; - -- size = type_size(type, &align); -+ size = type_size(st, type, &align); - /* If unknown size, we must evaluate it before - evaluating initializers because - initializers can generate global data too - (e.g. string pointers or ISOC99 compound - literals). It also simplifies local - initializers handling */ -- tok_str_new(&init_str); -+ tok_str_new(st, &init_str); - if (size < 0) { - if (!has_init) -- error("unknown type size"); -+ tcc_error(st, "unknown type size"); - /* get all init string */ - if (has_init == 2) { - /* only get strings */ - while (tok == TOK_STR || tok == TOK_LSTR) { -- tok_str_add_tok(&init_str); -- next(); -+ tok_str_add_tok(st, &init_str); -+ next(st); - } - } else { - level = 0; - while (level > 0 || (tok != ',' && tok != ';')) { - if (tok < 0) -- error("unexpected end of file in initializer"); -- tok_str_add_tok(&init_str); -+ tcc_error(st, "unexpected end of file in initializer"); -+ tok_str_add_tok(st, &init_str); - if (tok == '{') - level++; - else if (tok == '}') { -@@ -8632,26 +7947,26 @@ - break; - level--; - } -- next(); -+ next(st); - } - } -- tok_str_add(&init_str, -1); -- tok_str_add(&init_str, 0); -+ tok_str_add(st, &init_str, -1, 0); -+ tok_str_add(st, &init_str, 0, 0); - - /* compute size */ -- save_parse_state(&saved_parse_state); -+ save_parse_state(st, &saved_parse_state); - - macro_ptr = init_str.str; -- next(); -- decl_initializer(type, NULL, 0, 1, 1); -+ next(st); -+ decl_initializer(st, type, NULL, 0, 1, 1); - /* prepare second initializer parsing */ - macro_ptr = init_str.str; -- next(); -+ next(st); - - /* if still unknown size, error */ -- size = type_size(type, &align); -+ size = type_size(st, type, &align); - if (size < 0) -- error("unknown type size"); -+ tcc_error(st, "unknown type size"); - } - /* take into account specified alignment if bigger */ - if (ad->aligned) { -@@ -8674,16 +7989,16 @@ - /* add padding between regions */ - loc--; - /* then add local bound info */ -- bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long)); -+ bounds_ptr = section_ptr_add(st, lbounds_section, 2 * sizeof(unsigned long)); - bounds_ptr[0] = addr; - bounds_ptr[1] = size; - } - if (v) { - /* local variable */ -- sym_push(v, type, r, addr); -+ sym_push(st, v, type, r, addr); - } else { - /* push local reference */ -- vset(type, r, addr); -+ vset(st, type, r, addr); - } - } else { - Sym *sym; -@@ -8691,11 +8006,11 @@ - sym = NULL; - if (v && scope == VT_CONST) { - /* see if the symbol was already defined */ -- sym = sym_find(v); -+ sym = sym_find(st, v); - if (sym) { -- if (!is_compatible_types(&sym->type, type)) -- error("incompatible types for redefinition of '%s'", -- get_tok_str(v, NULL)); -+ if (!is_compatible_types(st, &sym->type, type)) -+ tcc_error(st, "incompatible types for redefinition of '%s'", -+ get_tok_str(st, v, NULL)); - if (sym->type.t & VT_EXTERN) { - /* if the variable is extern, it was not allocated */ - sym->type.t &= ~VT_EXTERN; -@@ -8724,7 +8039,7 @@ - if (!sec) { - if (has_init) - sec = data_section; -- else if (tcc_state->nocommon) -+ else if (st->nocommon) - sec = bss_section; - } - if (sec) { -@@ -8741,7 +8056,7 @@ - /* allocate section space to put the data */ - if (sec->sh_type != SHT_NOBITS && - data_offset > sec->data_allocated) -- section_realloc(sec, data_offset); -+ section_realloc(st, sec, data_offset); - /* align section if needed */ - if (align > sec->sh_addralign) - sec->sh_addralign = align; -@@ -8750,20 +8065,16 @@ - } - - if (v) { -- if (scope == VT_CONST) { -- if (!sym) -- goto do_def; -- } else { -- do_def: -- sym = sym_push(v, type, r | VT_SYM, 0); -+ if (scope != VT_CONST || !sym) { -+ sym = sym_push(st, v, type, r | VT_SYM, 0); - } - /* update symbol definition */ - if (sec) { -- put_extern_sym(sym, sec, addr, size); -+ put_extern_sym(st, sym, sec, addr, size); - } else { - Elf32_Sym *esym; - /* put a common area */ -- put_extern_sym(sym, NULL, align, size); -+ put_extern_sym(st, sym, NULL, align, size); - /* XXX: find a nicer way */ - esym = &((Elf32_Sym *)symtab_section->data)[sym->c]; - esym->st_shndx = SHN_COMMON; -@@ -8772,9 +8083,9 @@ - CValue cval; - - /* push global reference */ -- sym = get_sym_ref(type, sec, addr, size); -+ sym = get_sym_ref(st, type, sec, addr, size); - cval.ul = 0; -- vsetc(type, VT_CONST | VT_SYM, &cval); -+ vsetc(st, type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; - } - -@@ -8783,25 +8094,25 @@ - if (do_bounds_check) { - unsigned long *bounds_ptr; - -- greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32); -+ greloc(st, bounds_section, sym, bounds_section->data_offset, R_DATA_32); - /* then add global bound info */ -- bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long)); -+ bounds_ptr = section_ptr_add(st, bounds_section, 2 * sizeof(long)); - bounds_ptr[0] = 0; /* relocated */ - bounds_ptr[1] = size; - } - } - if (has_init) { -- decl_initializer(type, sec, addr, 1, 0); -+ decl_initializer(st, type, sec, addr, 1, 0); - /* restore parse state if needed */ - if (init_str.str) { -- tok_str_free(init_str.str); -- restore_parse_state(&saved_parse_state); -+ tok_str_free(st, init_str.str); -+ restore_parse_state(st, &saved_parse_state); - } - } - no_alloc: ; - } - --void put_func_debug(Sym *sym) -+void put_func_debug(TCCState *st, Sym *sym) - { - char buf[512]; - -@@ -8809,7 +8120,7 @@ - /* XXX: we put here a dummy type */ - snprintf(buf, sizeof(buf), "%s:%c1", - funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); -- put_stabs_r(buf, N_FUN, 0, file->line_num, 0, -+ put_stabs_r(st, buf, N_FUN, 0, file->line_num, 0, - cur_text_section, sym->c); - last_ind = 0; - last_line_num = 0; -@@ -8817,7 +8128,7 @@ - - /* parse an old style function declaration list */ - /* XXX: check multiple parameter */ --static void func_decl_list(Sym *func_sym) -+static void func_decl_list(TCCState *st, Sym *func_sym) - { - AttributeDef ad; - int v; -@@ -8826,8 +8137,8 @@ - - /* parse each declaration */ - while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) { -- if (!parse_btype(&btype, &ad)) -- expect("declaration list"); -+ if (!parse_btype(st, &btype, &ad)) -+ expect(st, "declaration list"); - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { -@@ -8835,7 +8146,7 @@ - } else { - for(;;) { - type = btype; -- type_decl(&type, &ad, &v, TYPE_DIRECT); -+ type_decl(st, &type, &ad, &v, TYPE_DIRECT); - /* find parameter in function parameter list */ - s = func_sym->next; - while (s != NULL) { -@@ -8843,61 +8154,61 @@ - goto found; - s = s->next; - } -- error("declaration for parameter '%s' but no such parameter", -- get_tok_str(v, NULL)); -+ tcc_error(st, "declaration for parameter '%s' but no such parameter", -+ get_tok_str(st, v, NULL)); - found: - /* check that no storage specifier except 'register' was given */ - if (type.t & VT_STORAGE) -- error("storage class specified for '%s'", get_tok_str(v, NULL)); -- convert_parameter_type(&type); -+ tcc_error(st, "storage class specified for '%s'", get_tok_str(st, v, NULL)); -+ convert_parameter_type(st, &type); - /* we can add the type (NOTE: it could be local to the function) */ - s->type = type; - /* accept other parameters */ - if (tok == ',') -- next(); -+ next(st); - else - break; - } - } -- skip(';'); -+ skip(st, ';'); - } - } - - /* parse a function defined by symbol 'sym' and generate its code in - 'cur_text_section' */ --static void gen_function(Sym *sym) -+static void gen_function(TCCState *st, Sym *sym) - { - ind = cur_text_section->data_offset; - /* NOTE: we patch the symbol size later */ -- put_extern_sym(sym, cur_text_section, ind, 0); -- funcname = get_tok_str(sym->v, NULL); -+ put_extern_sym(st, sym, cur_text_section, ind, 0); -+ funcname = get_tok_str(st, sym->v, NULL); - func_ind = ind; - /* put debug symbol */ - if (do_debug) -- put_func_debug(sym); -+ put_func_debug(st, sym); - /* push a dummy symbol to enable local sym storage */ -- sym_push2(&local_stack, SYM_FIELD, 0, 0); -- gfunc_prolog(&sym->type); -+ sym_push2(st, &local_stack, SYM_FIELD, 0, 0); -+ gfunc_prolog(st, &sym->type); - rsym = 0; -- block(NULL, NULL, NULL, NULL, 0, 0); -+ block(st, NULL, NULL, NULL, NULL, 0, 0); - gsym(rsym); -- gfunc_epilog(); -+ gfunc_epilog(st); - cur_text_section->data_offset = ind; -- label_pop(&global_label_stack, NULL); -- sym_pop(&local_stack, NULL); /* reset local stack */ -+ label_pop(st, &global_label_stack, NULL); -+ sym_pop(st, &local_stack, NULL); /* reset local stack */ - /* end of function */ - /* patch symbol size */ - ((Elf32_Sym *)symtab_section->data)[sym->c].st_size = - ind - func_ind; - if (do_debug) { -- put_stabn(N_FUN, 0, 0, ind - func_ind); -+ put_stabn(st, N_FUN, 0, 0, ind - func_ind); - } - funcname = ""; /* for safety */ - func_vt.t = VT_VOID; /* for safety */ - ind = 0; /* for safety */ - } - --static void gen_inline_functions(void) -+static void gen_inline_functions(TCCState *st) - { - Sym *sym; - CType *type; -@@ -8919,12 +8230,12 @@ - type->t &= ~VT_INLINE; - - macro_ptr = str; -- next(); -+ next(st); - cur_text_section = text_section; -- gen_function(sym); -+ gen_function(st, sym); - macro_ptr = NULL; /* fail safe */ - -- tok_str_free(str); -+ tok_str_free(st, str); - inline_generated = 1; - } - } -@@ -8939,14 +8250,14 @@ - (type->t & (VT_STATIC | VT_INLINE)) == - (VT_STATIC | VT_INLINE)) { - str = (int *)sym->r; -- tok_str_free(str); -+ tok_str_free(st, str); - sym->r = 0; /* fail safe */ - } - } - } - - /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ --static void decl(int l) -+static void decl(TCCState *st, int l) - { - int v, has_init, r; - CType type, btype; -@@ -8954,17 +8265,17 @@ - AttributeDef ad; - - while (1) { -- if (!parse_btype(&btype, &ad)) { -+ if (!parse_btype(st, &btype, &ad)) { - /* skip redundant ';' */ - /* XXX: find more elegant solution */ - if (tok == ';') { -- next(); -+ next(st); - continue; - } - if (l == VT_CONST && - (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { - /* global asm block */ -- asm_global_instr(); -+ asm_global_instr(st); - continue; - } - /* special test for old K&R protos without explicit int -@@ -8977,16 +8288,16 @@ - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - /* we accept no variable after */ -- next(); -+ next(st); - continue; - } - while (1) { /* iterate thru each declaration */ - type = btype; -- type_decl(&type, &ad, &v, TYPE_DIRECT); -+ type_decl(st, &type, &ad, &v, TYPE_DIRECT); - #if 0 - { - char buf[500]; -- type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL)); -+ type_to_str(st, buf, sizeof(buf), &type, get_tok_str(st, v, NULL)); - printf("type = '%s'\n", buf); - } - #endif -@@ -8995,26 +8306,28 @@ - declaration list */ - sym = type.ref; - if (sym->c == FUNC_OLD) -- func_decl_list(sym); -+ func_decl_list(st, sym); - } - -+ /* Open curly bracket here can only be a function body, because -+ struct and union contents are handled by parse_btype(st) above. */ - if (tok == '{') { - if (l == VT_LOCAL) -- error("cannot use local functions"); -- if (!(type.t & VT_FUNC)) -- expect("function definition"); -+ tcc_error(st, "cannot use local functions"); -+ if ((type.t & VT_BTYPE) != VT_FUNC) -+ expect(st, "function definition"); - - /* reject abstract declarators in function definition */ - sym = type.ref; - while ((sym = sym->next) != NULL) - if (!(sym->v & ~SYM_FIELD)) -- expect("identifier"); -+ expect(st, "identifier"); - -- /* XXX: cannot do better now: convert extern line to static inline */ -+ /* XXX: cannot do better now: convert extern inline to static inline */ - if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE)) - type.t = (type.t & ~VT_EXTERN) | VT_STATIC; - -- sym = sym_find(v); -+ sym = sym_find(st, v); - if (sym) { - if ((sym->type.t & VT_BTYPE) != VT_FUNC) - goto func_error1; -@@ -9024,16 +8337,16 @@ - if (sym->type.ref->r != FUNC_CDECL && - type.ref->r == FUNC_CDECL) - type.ref->r = sym->type.ref->r; -- if (!is_compatible_types(&sym->type, &type)) { -+ if (!is_compatible_types(st, &sym->type, &type)) { - func_error1: -- error("incompatible types for redefinition of '%s'", -- get_tok_str(v, NULL)); -+ tcc_error(st, "incompatible types for redefinition of '%s'", -+ get_tok_str(st, v, NULL)); - } - /* if symbol is already defined, then put complete type */ - sym->type = type; - } else { - /* put function symbol */ -- sym = global_identifier_push(v, type.t, 0); -+ sym = global_identifier_push(st, v, type.t, 0); - sym->type.ref = type.ref; - } - -@@ -9045,16 +8358,16 @@ - TokenString func_str; - int block_level; - -- tok_str_new(&func_str); -+ tok_str_new(st, &func_str); - - block_level = 0; - for(;;) { - int t; - if (tok == TOK_EOF) -- error("unexpected end of file"); -- tok_str_add_tok(&func_str); -+ tcc_error(st, "unexpected end of file"); -+ tok_str_add_tok(st, &func_str); - t = tok; -- next(); -+ next(st); - if (t == '{') { - block_level++; - } else if (t == '}') { -@@ -9063,8 +8376,8 @@ - break; - } - } -- tok_str_add(&func_str, -1); -- tok_str_add(&func_str, 0); -+ tok_str_add(st, &func_str, -1, 0); -+ tok_str_add(st, &func_str, 0, 0); - sym->r = (int)func_str.str; - } else { - /* compute text section */ -@@ -9072,31 +8385,33 @@ - if (!cur_text_section) - cur_text_section = text_section; - sym->r = VT_SYM | VT_CONST; -- gen_function(sym); --#ifdef TCC_TARGET_PE -+ gen_function(st, sym); -+#ifdef WIN32 - if (ad.dllexport) { - ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1; - } - #endif - } - break; -+ -+ /* If there was no function body, it must be a varaible. */ - } else { - if (btype.t & VT_TYPEDEF) { - /* save typedefed type */ - /* XXX: test storage specifiers ? */ -- sym = sym_push(v, &type, 0, 0); -+ sym = sym_push(st, v, &type, 0, 0); - sym->type.t |= VT_TYPEDEF; - } else if ((type.t & VT_BTYPE) == VT_FUNC) { - /* external function definition */ - /* specific case for func_call attribute */ - if (ad.func_call) - type.ref->r = ad.func_call; -- external_sym(v, &type, 0); -+ external_sym(st, v, &type, 0); - } else { - /* not lvalue if array */ - r = 0; - if (!(type.t & VT_ARRAY)) -- r |= lvalue_type(type.t); -+ r |= lvalue_type(st, type.t); - has_init = (tok == '='); - if ((btype.t & VT_EXTERN) || - ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && -@@ -9105,23 +8420,24 @@ - /* NOTE: as GCC, uninitialized global static - arrays of null size are considered as - extern */ -- external_sym(v, &type, r); -+ external_sym(st, v, &type, r); - } else { -+ type.t |= (btype.t & VT_STATIC); /* Retain "static". */ - if (type.t & VT_STATIC) - r |= VT_CONST; - else - r |= l; - if (has_init) -- next(); -- decl_initializer_alloc(&type, &ad, r, -+ next(st); -+ decl_initializer_alloc(st, &type, &ad, r, - has_init, v, l); - } - } - if (tok != ',') { -- skip(';'); -+ skip(st, ';'); - break; - } -- next(); -+ next(st); - } - } - } -@@ -9129,22 +8445,21 @@ - - /* better than nothing, but needs extension to handle '-E' option - correctly too */ --static void preprocess_init(TCCState *s1) -+static void preprocess_init(TCCState *st) - { -- s1->include_stack_ptr = s1->include_stack; -+ st->include_stack_ptr = st->include_stack; - /* XXX: move that before to avoid having to initialize - file->ifdef_stack_ptr ? */ -- s1->ifdef_stack_ptr = s1->ifdef_stack; -- file->ifdef_stack_ptr = s1->ifdef_stack_ptr; -+ st->ifdef_stack_ptr = st->ifdef_stack; -+ file->ifdef_stack_ptr = st->ifdef_stack_ptr; - -- /* XXX: not ANSI compliant: bound checking says error */ -- vtop = vstack - 1; -- s1->pack_stack[0] = 0; -- s1->pack_stack_ptr = s1->pack_stack; -+ vtop = vstack; -+ st->pack_stack[0] = 0; -+ st->pack_stack_ptr = st->pack_stack; - } - - /* compile the C file opened in 'file'. Return non zero if errors. */ --static int tcc_compile(TCCState *s1) -+static int tcc_compile(TCCState *st) - { - Sym *define_start; - char buf[512]; -@@ -9153,7 +8468,7 @@ - #ifdef INC_DEBUG - printf("%s: **** new file\n", file->filename); - #endif -- preprocess_init(s1); -+ preprocess_init(st); - - funcname = ""; - anon_sym = SYM_FIRST_ANOM; -@@ -9161,19 +8476,19 @@ - /* file info: full path + filename */ - section_sym = 0; /* avoid warning */ - if (do_debug) { -- section_sym = put_elf_sym(symtab_section, 0, 0, -+ section_sym = put_elf_sym(st, symtab_section, 0, 0, - ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0, - text_section->sh_num, NULL); - getcwd(buf, sizeof(buf)); -- pstrcat(buf, sizeof(buf), "/"); -- put_stabs_r(buf, N_SO, 0, 0, -+ pstrcat(st, buf, sizeof(buf), "/"); -+ put_stabs_r(st, buf, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); -- put_stabs_r(file->filename, N_SO, 0, 0, -+ put_stabs_r(st, file->filename, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - } - /* an elf symbol of type STT_FILE must be put so that STB_LOCAL - symbols can be safely used */ -- put_elf_sym(symtab_section, 0, 0, -+ put_elf_sym(st, symtab_section, 0, 0, - ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0, - SHN_ABS, file->filename); - -@@ -9181,56 +8496,106 @@ - int_type.t = VT_INT; - - char_pointer_type.t = VT_BYTE; -- mk_pointer(&char_pointer_type); -+ mk_pointer(st, &char_pointer_type); - - func_old_type.t = VT_FUNC; -- func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); -+ func_old_type.ref = sym_push(st, SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); -+ -+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) -+ float_type.t = VT_FLOAT; -+ double_type.t = VT_DOUBLE; -+ -+ func_float_type.t = VT_FUNC; -+ func_float_type.ref = sym_push(st, SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD); -+ func_double_type.t = VT_FUNC; -+ func_double_type.ref = sym_push(st, SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD); -+#endif - - #if 0 - /* define 'void *alloca(unsigned int)' builtin function */ - { -- Sym *s1; -+ Sym *st; - - p = anon_sym++; -- sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); -- s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); -- s1->next = NULL; -- sym->next = s1; -- sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); -+ sym = sym_push(st, p, mk_pointer(st, VT_VOID), FUNC_CDECL, FUNC_NEW); -+ st = sym_push(st, SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); -+ st->next = NULL; -+ sym->next = st; -+ sym_push(st, TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); - } - #endif - - define_start = define_stack; - -- if (setjmp(s1->error_jmp_buf) == 0) { -- s1->nb_errors = 0; -- s1->error_set_jmp_enabled = 1; -+ if (setjmp(st->error_jmp_buf) == 0) { -+ st->nb_errors = 0; -+ st->error_set_jmp_enabled = 1; - -- ch = file->buf_ptr[0]; -- tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; -+ fch = file->buf_ptr[0]; -+ next_tok_flags = TOK_FLAG_BOW | TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM; -- next(); -- decl(VT_CONST); -- if (tok != TOK_EOF) -- expect("declaration"); -+ next(st); -+ decl(st, VT_CONST); -+ if (tok != TOK_EOF) expect(st, "declaration"); - - /* end of translation unit info */ - if (do_debug) { -- put_stabs_r(NULL, N_SO, 0, 0, -- text_section->data_offset, text_section, section_sym); -+ put_stabs_r(st, NULL, N_SO, 0, 0, text_section->data_offset, -+ text_section, section_sym); - } - } -- s1->error_set_jmp_enabled = 0; -+ st->error_set_jmp_enabled = 0; - - /* reset define stack, but leave -Dsymbols (may be incorrect if - they are undefined) */ -- free_defines(define_start); -+ free_defines(st, define_start); -+ -+ gen_inline_functions(st); - -- gen_inline_functions(); -+ sym_pop(st, &global_stack, NULL); - -- sym_pop(&global_stack, NULL); -+ return st->nb_errors != 0 ? -1 : 0; -+} -+ -+/* Preprocess the current file */ -+/* XXX: add line and file infos, add options to preserve spaces */ -+static int tcc_preprocess(TCCState *st) -+{ -+ Sym *define_start; -+ int last_is_space; -+ -+ preprocess_init(st); - -- return s1->nb_errors != 0 ? -1 : 0; -+ define_start = define_stack; -+ -+ fch = file->buf_ptr[0]; -+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; -+ parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS | -+ PARSE_FLAG_LINEFEED; -+ last_is_space = 1; -+ next(st); -+ for(;;) { -+ if (tok == TOK_EOF) -+ break; -+ if (!last_is_space) { -+ fputc(' ', st->outfile); -+ } -+ fputs(get_tok_str(st, tok, &tokc), st->outfile); -+ if (tok == TOK_LINEFEED) { -+ last_is_space = 1; -+ /* XXX: suppress that hack */ -+ parse_flags &= ~PARSE_FLAG_LINEFEED; -+ next(st); -+ parse_flags |= PARSE_FLAG_LINEFEED; -+ } else { -+ last_is_space = 0; -+ next(st); -+ } -+ } -+ -+ free_defines(st, define_start); -+ -+ return 0; - } - - #ifdef LIBTCC -@@ -9241,23 +8606,23 @@ - char *buf; - - /* init file structure */ -- bf->fd = -1; -+ bf->fd = NULL; - /* XXX: avoid copying */ - len = strlen(str); -- buf = tcc_malloc(len + 1); -+ buf = tcc_malloc(s, len + 1); - if (!buf) - return -1; - memcpy(buf, str, len); - buf[len] = CH_EOB; - bf->buf_ptr = buf; - bf->buf_end = buf + len; -- pstrcpy(bf->filename, sizeof(bf->filename), ""); -+ pstrcpy(s, bf->filename, sizeof(bf->filename), ""); - bf->line_num = 1; - file = bf; - - ret = tcc_compile(s); - -- tcc_free(buf); -+ ckfree((char *)buf); - - /* currently, no need to close */ - return ret; -@@ -9265,19 +8630,19 @@ - #endif - - /* define a preprocessor symbol. A value can also be provided with the '=' operator */ --void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) -+void tcc_define_symbol(TCCState *st, const char *sym, const char *value) - { - BufferedFile bf1, *bf = &bf1; - -- pstrcpy(bf->buffer, IO_BUF_SIZE, sym); -- pstrcat(bf->buffer, IO_BUF_SIZE, " "); -+ pstrcpy(st, bf->buffer, IO_BUF_SIZE, sym); -+ pstrcat(st, bf->buffer, IO_BUF_SIZE, " "); - /* default value */ - if (!value) - value = "1"; -- pstrcat(bf->buffer, IO_BUF_SIZE, value); -+ pstrcat(st, bf->buffer, IO_BUF_SIZE, value); - - /* init file structure */ -- bf->fd = -1; -+ bf->fd = NULL; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer + strlen(bf->buffer); - *bf->buf_end = CH_EOB; -@@ -9285,22 +8650,22 @@ - bf->line_num = 1; - file = bf; - -- s1->include_stack_ptr = s1->include_stack; -+ st->include_stack_ptr = st->include_stack; - - /* parse with define parser */ -- ch = file->buf_ptr[0]; -- next_nomacro(); -- parse_define(); -+ fch = file->buf_ptr[0]; -+ next_nomacro(st); -+ parse_define(st); - file = NULL; - } - - /* undefine a preprocessor symbol */ --void tcc_undefine_symbol(TCCState *s1, const char *sym) -+void tcc_undefine_symbol(TCCState *st, const char *sym) - { - TokenSym *ts; - Sym *s; -- ts = tok_alloc(sym, strlen(sym)); -- s = define_find(ts->tok); -+ ts = tok_alloc(st, sym, strlen(sym)); -+ s = define_find(st, ts->tok); - /* undefine symbol by putting an invalid name */ - if (s) - define_undef(s); -@@ -9309,18 +8674,18 @@ - #ifdef CONFIG_TCC_ASM - - #ifdef TCC_TARGET_I386 --#include "i386-asm.c" -+#include "i386/i386-asm.c" - #endif - #include "tccasm.c" - - #else --static void asm_instr(void) -+static void asm_instr(TCCState *st) - { -- error("inline asm() not supported"); -+ tcc_error(st, "inline asm() not supported"); - } --static void asm_global_instr(void) -+static void asm_global_instr(TCCState *st) - { -- error("inline asm() not supported"); -+ tcc_error(st, "inline asm() not supported"); - } - #endif - -@@ -9330,354 +8695,121 @@ - #include "tcccoff.c" - #endif - --#ifdef TCC_TARGET_PE --#include "tccpe.c" --#endif -- --/* print the position in the source file of PC value 'pc' by reading -- the stabs debug information */ --static void rt_printline(unsigned long wanted_pc) --{ -- Stab_Sym *sym, *sym_end; -- char func_name[128], last_func_name[128]; -- unsigned long func_addr, last_pc, pc; -- const char *incl_files[INCLUDE_STACK_SIZE]; -- int incl_index, len, last_line_num, i; -- const char *str, *p; -- -- fprintf(stderr, "0x%08lx:", wanted_pc); -- -- func_name[0] = '\0'; -- func_addr = 0; -- incl_index = 0; -- last_func_name[0] = '\0'; -- last_pc = 0xffffffff; -- last_line_num = 1; -- sym = (Stab_Sym *)stab_section->data + 1; -- sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); -- while (sym < sym_end) { -- switch(sym->n_type) { -- /* function start or end */ -- case N_FUN: -- if (sym->n_strx == 0) { -- /* we test if between last line and end of function */ -- pc = sym->n_value + func_addr; -- if (wanted_pc >= last_pc && wanted_pc < pc) -- goto found; -- func_name[0] = '\0'; -- func_addr = 0; -- } else { -- str = stabstr_section->data + sym->n_strx; -- p = strchr(str, ':'); -- if (!p) { -- pstrcpy(func_name, sizeof(func_name), str); -- } else { -- len = p - str; -- if (len > sizeof(func_name) - 1) -- len = sizeof(func_name) - 1; -- memcpy(func_name, str, len); -- func_name[len] = '\0'; -- } -- func_addr = sym->n_value; -- } -- break; -- /* line number info */ -- case N_SLINE: -- pc = sym->n_value + func_addr; -- if (wanted_pc >= last_pc && wanted_pc < pc) -- goto found; -- last_pc = pc; -- last_line_num = sym->n_desc; -- /* XXX: slow! */ -- strcpy(last_func_name, func_name); -- break; -- /* include files */ -- case N_BINCL: -- str = stabstr_section->data + sym->n_strx; -- add_incl: -- if (incl_index < INCLUDE_STACK_SIZE) { -- incl_files[incl_index++] = str; -- } -- break; -- case N_EINCL: -- if (incl_index > 1) -- incl_index--; -- break; -- case N_SO: -- if (sym->n_strx == 0) { -- incl_index = 0; /* end of translation unit */ -- } else { -- str = stabstr_section->data + sym->n_strx; -- /* do not add path */ -- len = strlen(str); -- if (len > 0 && str[len - 1] != '/') -- goto add_incl; -- } -- break; -- } -- sym++; -- } -- -- /* second pass: we try symtab symbols (no line number info) */ -- incl_index = 0; -- { -- Elf32_Sym *sym, *sym_end; -- int type; -- -- sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset); -- for(sym = (Elf32_Sym *)symtab_section->data + 1; -- sym < sym_end; -- sym++) { -- type = ELF32_ST_TYPE(sym->st_info); -- if (type == STT_FUNC) { -- if (wanted_pc >= sym->st_value && -- wanted_pc < sym->st_value + sym->st_size) { -- pstrcpy(last_func_name, sizeof(last_func_name), -- strtab_section->data + sym->st_name); -- goto found; -- } -- } -- } -- } -- /* did not find any info: */ -- fprintf(stderr, " ???\n"); -- return; -- found: -- if (last_func_name[0] != '\0') { -- fprintf(stderr, " %s()", last_func_name); -- } -- if (incl_index > 0) { -- fprintf(stderr, " (%s:%d", -- incl_files[incl_index - 1], last_line_num); -- for(i = incl_index - 2; i >= 0; i--) -- fprintf(stderr, ", included from %s", incl_files[i]); -- fprintf(stderr, ")"); -- } -- fprintf(stderr, "\n"); --} -- --#if !defined(WIN32) && !defined(CONFIG_TCCBOOT) -- --#ifdef __i386__ -- --/* fix for glibc 2.1 */ --#ifndef REG_EIP --#define REG_EIP EIP --#define REG_EBP EBP --#endif -- --/* return the PC at frame level 'level'. Return non zero if not found */ --static int rt_get_caller_pc(unsigned long *paddr, -- ucontext_t *uc, int level) --{ -- unsigned long fp; -- int i; -- -- if (level == 0) { --#if defined(__FreeBSD__) -- *paddr = uc->uc_mcontext.mc_eip; --#elif defined(__dietlibc__) -- *paddr = uc->uc_mcontext.eip; --#else -- *paddr = uc->uc_mcontext.gregs[REG_EIP]; --#endif -- return 0; -- } else { --#if defined(__FreeBSD__) -- fp = uc->uc_mcontext.mc_ebp; --#elif defined(__dietlibc__) -- fp = uc->uc_mcontext.ebp; --#else -- fp = uc->uc_mcontext.gregs[REG_EBP]; --#endif -- for(i=1;i= 0xc0000000) -- return -1; -- fp = ((unsigned long *)fp)[0]; -- } -- *paddr = ((unsigned long *)fp)[1]; -- return 0; -- } --} --#else -- --#warning add arch specific rt_get_caller_pc() -- --static int rt_get_caller_pc(unsigned long *paddr, -- ucontext_t *uc, int level) --{ -- return -1; --} --#endif -- --/* emit a run time error at position 'pc' */ --void rt_error(ucontext_t *uc, const char *fmt, ...) --{ -- va_list ap; -- unsigned long pc; -- int i; -- -- va_start(ap, fmt); -- fprintf(stderr, "Runtime error: "); -- vfprintf(stderr, fmt, ap); -- fprintf(stderr, "\n"); -- for(i=0;isi_code) { -- case FPE_INTDIV: -- case FPE_FLTDIV: -- rt_error(uc, "division by zero"); -- break; -- default: -- rt_error(uc, "floating point exception"); -- break; -- } -- break; -- case SIGBUS: -- case SIGSEGV: -- if (rt_bound_error_msg && *rt_bound_error_msg) -- rt_error(uc, *rt_bound_error_msg); -- else -- rt_error(uc, "dereferencing invalid pointer"); -- break; -- case SIGILL: -- rt_error(uc, "illegal instruction"); -- break; -- case SIGABRT: -- rt_error(uc, "abort() called"); -- break; -- default: -- rt_error(uc, "caught signal %d", signum); -- break; -- } -- exit(255); --} -+#ifdef WIN32 -+#include "win32/tccpe.c" - #endif - --/* do all relocations (needed before using tcc_get_symbol()) */ --int tcc_relocate(TCCState *s1) -+/* do all relocations (needed before using tcc_get_symbol(st)) */ -+int tcc_relocate(TCCState *st) - { - Section *s; - int i; - -- s1->nb_errors = 0; -+ st->nb_errors = 0; - --#ifdef TCC_TARGET_PE -- pe_add_runtime(s1); -+#ifdef WIN32 -+ pe_add_runtime(st); - #else -- tcc_add_runtime(s1); -+ tcc_add_runtime(st); - #endif - - relocate_common_syms(); -- -- tcc_add_linker_symbols(s1); -- -- build_got_entries(s1); -+ tcc_add_linker_symbols(st); -+ build_got_entries(st); - - /* compute relocation address : section are relocated in place. We - also alloc the bss space */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - if (s->sh_flags & SHF_ALLOC) { - if (s->sh_type == SHT_NOBITS) -- s->data = tcc_mallocz(s->data_offset); -+ s->data = tcc_mallocz(st, s->data_offset); - s->sh_addr = (unsigned long)s->data; - } - } - -- relocate_syms(s1, 1); -+ relocate_syms(st, 1); - -- if (s1->nb_errors != 0) -+ if (st->nb_errors != 0) - return -1; - - /* relocate each section */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - if (s->reloc) -- relocate_section(s1, s); -+ relocate_section(st, s); -+ } -+ -+ /* mark executable sections as executable in memory */ -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; -+ if ((s->sh_flags & (SHF_ALLOC | SHF_EXECINSTR)) == -+ (SHF_ALLOC | SHF_EXECINSTR)) { -+#ifdef WIN32 -+ { -+ int old_protect; -+ VirtualProtect(s->data, s->data_offset, -+ PAGE_EXECUTE_READWRITE, &old_protect); -+ } -+#else -+ { -+ unsigned long start, end; -+ start = (unsigned long)(s->data) & ~(PAGESIZE - 1); -+ end = (unsigned long)(s->data + s->data_offset); -+ end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); -+ mprotect((void *)start, end - start, -+ PROT_READ | PROT_WRITE | PROT_EXEC); -+ } -+#endif -+ } - } - return 0; - } - - /* launch the compiled program with the given arguments */ --int tcc_run(TCCState *s1, int argc, char **argv) -+int tcc_run(TCCState *st, int argc, char **argv) - { - int (*prog_main)(int, char **); - -- if (tcc_relocate(s1) < 0) -+ if (tcc_relocate(st) < 0) - return -1; - -- prog_main = tcc_get_symbol_err(s1, "main"); -+ prog_main = tcc_get_symbol_err(st, "main"); - -- if (do_debug) { --#if defined(WIN32) || defined(CONFIG_TCCBOOT) -- error("debug mode currently not available for Windows"); --#else -- struct sigaction sigact; -- /* install TCC signal handlers to print debug info on fatal -- runtime errors */ -- sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; -- sigact.sa_sigaction = sig_error; -- sigemptyset(&sigact.sa_mask); -- sigaction(SIGFPE, &sigact, NULL); -- sigaction(SIGILL, &sigact, NULL); -- sigaction(SIGSEGV, &sigact, NULL); -- sigaction(SIGBUS, &sigact, NULL); -- sigaction(SIGABRT, &sigact, NULL); --#endif -- } -- --#ifdef CONFIG_TCC_BCHECK -+#if 0 - if (do_bounds_check) { - void (*bound_init)(void); - - /* set error function */ -- rt_bound_error_msg = (void *)tcc_get_symbol_err(s1, -+ rt_bound_error_msg = (void *)tcc_get_symbol_err(st, - "__bound_error_msg"); - - /* XXX: use .init section so that it also work in binary ? */ -- bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init"); -- bound_init(); -+ bound_init = (void *)tcc_get_symbol_err(st, "__bound_init"); -+ bound_init(st); - } - #endif - return (*prog_main)(argc, argv); - } - --TCCState *tcc_new(void) -+TCCState *tcc_new(Tcl_Obj * libpath) - { - const char *p, *r; - TCCState *s; - TokenSym *ts; - int i, c; - -- s = tcc_mallocz(sizeof(TCCState)); -+ s = tcc_mallocz(NULL, sizeof(TCCState)); - if (!s) - return NULL; -- tcc_state = s; - s->output_type = TCC_OUTPUT_MEMORY; - -+ Tcl_IncrRefCount(libpath); -+ s->tcc_lib_path = libpath ; -+ - /* init isid table */ - for(i=0;i<256;i++) -- isidnum_table[i] = isid(i) || isnum(i); -+ isidnum_table[i] = isid(s, i) || isnum(s, i); - - /* add all tokens */ - table_ident = NULL; -@@ -9692,19 +8824,20 @@ - if (c == '\0') - break; - } -- ts = tok_alloc(p, r - p - 1); -+ ts = tok_alloc(s, p, r - p - 1); - p = r; - } - - /* we add dummy defines for some special macros to speed up tests - and to have working defined() */ -- define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL); -- define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); -- define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); -- define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); -+ define_push(s, TOK___LINE__, MACRO_OBJ, NULL, NULL); -+ define_push(s, TOK___FILE__, MACRO_OBJ, NULL, NULL); -+ define_push(s, TOK___DATE__, MACRO_OBJ, NULL, NULL); -+ define_push(s, TOK___TIME__, MACRO_OBJ, NULL, NULL); - - /* standard defines */ - tcc_define_symbol(s, "__STDC__", NULL); -+ tcc_define_symbol(s, "__STDC_VERSION__", "199901L"); - #if defined(TCC_TARGET_I386) - tcc_define_symbol(s, "__i386__", NULL); - #endif -@@ -9728,23 +8861,27 @@ - /* tiny C & gcc defines */ - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int"); -+#ifdef WIN32 -+ tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); -+#else - tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); -+#endif - - /* default library paths */ --#ifdef TCC_TARGET_PE - { - char buf[1024]; -- snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path); -+ snprintf(buf, sizeof(buf), "%s/lib", Tcl_GetString(s->tcc_lib_path)); -+ /* printf("default libraries %s\n",buf); */ - tcc_add_library_path(s, buf); - } --#else -+#ifndef WIN32 - tcc_add_library_path(s, "/usr/local/lib"); - tcc_add_library_path(s, "/usr/lib"); - tcc_add_library_path(s, "/lib"); - #endif - - /* no section zero */ -- dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); -+ dynarray_add(s, (void ***)&s->sections, &s->nb_sections, NULL); - - /* create standard sections */ - text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); -@@ -9766,87 +8903,92 @@ - #ifdef CHAR_IS_UNSIGNED - s->char_is_unsigned = 1; - #endif --#if defined(TCC_TARGET_PE) && 0 -+#if defined(WIN32) && 0 - /* XXX: currently the PE linker is not ready to support that */ - s->leading_underscore = 1; - #endif - return s; - } - --void tcc_delete(TCCState *s1) -+void tcc_delete(TCCState *st) - { -+ /* this leaks but allows you to reuse handles without crashing the process */ - int i, n; - - /* free -D defines */ -- free_defines(NULL); -+ free_defines(st, NULL); - - /* free tokens */ -+ if(0) { - n = tok_ident - TOK_IDENT; - for(i = 0; i < n; i++) -- tcc_free(table_ident[i]); -- tcc_free(table_ident); -+ ckfree((char *)(table_ident[i])); -+ ckfree((char *)table_ident); - - /* free all sections */ - -- free_section(symtab_section->hash); - -- free_section(s1->dynsymtab_section->hash); -- free_section(s1->dynsymtab_section->link); -- free_section(s1->dynsymtab_section); -- -- for(i = 1; i < s1->nb_sections; i++) -- free_section(s1->sections[i]); -- tcc_free(s1->sections); -+ free_section(st, symtab_section->hash); -+ -+ free_section(st, st->dynsymtab_section->hash); -+ free_section(st, st->dynsymtab_section->link); -+ free_section(st, st->dynsymtab_section); -+ -+ for(i = 1; i < st->nb_sections; i++) -+ free_section(st, st->sections[i]); -+ ckfree((char *)(st->sections)); -+ } - - /* free loaded dlls array */ -- for(i = 0; i < s1->nb_loaded_dlls; i++) -- tcc_free(s1->loaded_dlls[i]); -- tcc_free(s1->loaded_dlls); -+ for(i = 0; i < st->nb_loaded_dlls; i++) -+ ckfree((char *)(st->loaded_dlls[i])); -+ ckfree((char *)(st->loaded_dlls)); - - /* library paths */ -- for(i = 0; i < s1->nb_library_paths; i++) -- tcc_free(s1->library_paths[i]); -- tcc_free(s1->library_paths); -+ for(i = 0; i < st->nb_library_paths; i++) -+ ckfree((char *)(st->library_paths[i])); -+ ckfree((char *)(st->library_paths)); - - /* cached includes */ -- for(i = 0; i < s1->nb_cached_includes; i++) -- tcc_free(s1->cached_includes[i]); -- tcc_free(s1->cached_includes); -+ for(i = 0; i < st->nb_cached_includes; i++) -+ ckfree((char *)(st->cached_includes[i])); -+ ckfree((char *)(st->cached_includes)); - -- for(i = 0; i < s1->nb_include_paths; i++) -- tcc_free(s1->include_paths[i]); -- tcc_free(s1->include_paths); -+ for(i = 0; i < st->nb_include_paths; i++) -+ ckfree((char *)(st->include_paths[i])); -+ ckfree((char *)(st->include_paths)); - -- for(i = 0; i < s1->nb_sysinclude_paths; i++) -- tcc_free(s1->sysinclude_paths[i]); -- tcc_free(s1->sysinclude_paths); -+ for(i = 0; i < st->nb_sysinclude_paths; i++) -+ ckfree((char *)(st->sysinclude_paths[i])); -+ ckfree((char *)(st->sysinclude_paths)); - -- tcc_free(s1); -+ ckfree((char *)st); - } - --int tcc_add_include_path(TCCState *s1, const char *pathname) -+int tcc_add_include_path(TCCState *st, const char *pathname) - { - char *pathname1; - -- pathname1 = tcc_strdup(pathname); -- dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1); -+ pathname1 = tcc_strdup(st, pathname); -+ dynarray_add(st, (void ***)&st->include_paths, &st->nb_include_paths, pathname1); - return 0; - } - --int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) -+int tcc_add_sysinclude_path(TCCState *st, const char *pathname) - { - char *pathname1; - -- pathname1 = tcc_strdup(pathname); -- dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1); -+ pathname1 = tcc_strdup(st, pathname); -+ dynarray_add(st, (void ***)&st->sysinclude_paths, &st->nb_sysinclude_paths, pathname1); - return 0; - } - --static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) -+static int tcc_add_file_internal(TCCState *st, const char *filename, int flags) - { - const char *ext, *filename1; - Elf32_Ehdr ehdr; -- int fd, ret; -+ Tcl_Channel fd; -+ int ret; - BufferedFile *saved_file; - - /* find source file type with extension */ -@@ -9861,40 +9003,41 @@ - - /* open the file */ - saved_file = file; -- file = tcc_open(s1, filename); -+ file = tcc_open(st, filename); - if (!file) { - if (flags & AFF_PRINT_ERROR) { -- error_noabort("file '%s' not found", filename); -+ error_noabort(st, "file '%s' not found", filename); - } - ret = -1; - goto fail1; - } - -- if (!ext || !strcmp(ext, "c")) { -+ if (flags & AFF_PREPROCESS) ret = tcc_preprocess(st); -+ else if (!ext || !strcmp(ext, "c")) { - /* C file assumed */ -- ret = tcc_compile(s1); -+ ret = tcc_compile(st); - } else - #ifdef CONFIG_TCC_ASM - if (!strcmp(ext, "S")) { - /* preprocessed assembler */ -- ret = tcc_assemble(s1, 1); -+ ret = tcc_assemble(st, 1); - } else if (!strcmp(ext, "s")) { - /* non preprocessed assembler */ -- ret = tcc_assemble(s1, 0); -+ ret = tcc_assemble(st, 0); - } else - #endif --#ifdef TCC_TARGET_PE -+#ifdef WIN32 - if (!strcmp(ext, "def")) { -- ret = pe_load_def_file(s1, fdopen(file->fd, "rb")); -+ ret = pe_load_def_file(st, file->fd); - } else - #endif - { - fd = file->fd; - /* assume executable format: auto guess file type */ -- ret = read(fd, &ehdr, sizeof(ehdr)); -- lseek(fd, 0, SEEK_SET); -+ ret = Tcl_Read(fd, (char *)&ehdr, sizeof(ehdr)); -+ Tcl_Seek(fd, 0, SEEK_SET); - if (ret <= 0) { -- error_noabort("could not read header"); -+ error_noabort(st, "could not read header"); - goto fail; - } else if (ret != sizeof(ehdr)) { - goto try_load_script; -@@ -9906,10 +9049,10 @@ - ehdr.e_ident[3] == ELFMAG3) { - file->line_num = 0; /* do not display line number if error */ - if (ehdr.e_type == ET_REL) { -- ret = tcc_load_object_file(s1, fd, 0); -+ ret = tcc_load_object_file(st, fd, 0); - } else if (ehdr.e_type == ET_DYN) { -- if (s1->output_type == TCC_OUTPUT_MEMORY) { --#ifdef TCC_TARGET_PE -+ if (st->output_type == TCC_OUTPUT_MEMORY) { -+#ifdef WIN32 - ret = -1; - #else - void *h; -@@ -9920,28 +9063,28 @@ - ret = -1; - #endif - } else { -- ret = tcc_load_dll(s1, fd, filename, -+ ret = tcc_load_dll(st, fd, filename, - (flags & AFF_REFERENCED_DLL) != 0); - } - } else { -- error_noabort("unrecognized ELF file"); -+ error_noabort(st, "unrecognized ELF file"); - goto fail; - } - } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) { - file->line_num = 0; /* do not display line number if error */ -- ret = tcc_load_archive(s1, fd); -+ ret = tcc_load_archive(st, fd); - } else - #ifdef TCC_TARGET_COFF - if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) { -- ret = tcc_load_coff(s1, fd); -+ ret = tcc_load_coff(st, fd); - } else - #endif - { - /* as GNU ld, consider it is an ld script if not recognized */ - try_load_script: -- ret = tcc_load_ldscript(s1); -+ ret = tcc_load_ldscript(st); - if (ret < 0) { -- error_noabort("unrecognized file type"); -+ error_noabort(st, "unrecognized file type"); - goto fail; - } - } -@@ -9965,8 +9108,8 @@ - { - char *pathname1; - -- pathname1 = tcc_strdup(pathname); -- dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1); -+ pathname1 = tcc_strdup(s, pathname); -+ dynarray_add(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname1); - return 0; - } - -@@ -9994,7 +9137,7 @@ - - /* first we look for the dynamic library if not static linking */ - if (!s->static_link) { --#ifdef TCC_TARGET_PE -+#ifdef WIN32 - snprintf(buf, sizeof(buf), "%s.def", libraryname); - #else - snprintf(buf, sizeof(buf), "lib%s.so", libraryname); -@@ -10013,9 +9156,9 @@ - return -1; - } - --int tcc_add_symbol(TCCState *s, const char *name, unsigned long val) -+int tcc_add_symbol(TCCState *st, const char *name, unsigned long val) - { -- add_elf_sym(symtab_section, val, 0, -+ add_elf_sym(st, symtab_section, val, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - SHN_ABS, name); - return 0; -@@ -10030,20 +9173,20 @@ - - /* default include paths */ - /* XXX: reverse order needed if -isystem support */ --#ifndef TCC_TARGET_PE -+#ifndef WIN32 - tcc_add_sysinclude_path(s, "/usr/local/include"); - tcc_add_sysinclude_path(s, "/usr/include"); - #endif -- snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path); -+ snprintf(buf, sizeof(buf), "%s/include", Tcl_GetString(s->tcc_lib_path)); - tcc_add_sysinclude_path(s, buf); --#ifdef TCC_TARGET_PE -- snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path); -+#ifdef WIN32 -+ snprintf(buf, sizeof(buf), "%s/include/winapi", Tcl_GetString(s->tcc_lib_path)); - tcc_add_sysinclude_path(s, buf); - #endif - } - - /* if bound checking, then add corresponding sections */ --#ifdef CONFIG_TCC_BCHECK -+#if 0 - if (do_bounds_check) { - /* define symbol */ - tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); -@@ -10065,14 +9208,14 @@ - stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); - stab_section->sh_entsize = sizeof(Stab_Sym); - stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); -- put_elf_str(stabstr_section, ""); -+ put_elf_str(s, stabstr_section, ""); - stab_section->link = stabstr_section; - /* put first entry */ -- put_stabs("", 0, 0, 0, 0); -+ put_stabs(s, "", 0, 0, 0, 0); - } - - /* add libc crt1/crti objects */ --#ifndef TCC_TARGET_PE -+#ifndef WIN32 - if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && - !s->nostdlib) { - if (output_type != TCC_OUTPUT_DLL) -@@ -10157,8 +9300,6 @@ - flag_name, value); - } - --#if !defined(LIBTCC) -- - /* extract the basename of a file */ - static const char *tcc_basename(const char *name) - { -@@ -10175,516 +9316,4 @@ - return p; - } - --static int64_t getclock_us(void) --{ --#ifdef WIN32 -- struct _timeb tb; -- _ftime(&tb); -- return (tb.time * 1000LL + tb.millitm) * 1000LL; --#else -- struct timeval tv; -- gettimeofday(&tv, NULL); -- return tv.tv_sec * 1000000LL + tv.tv_usec; --#endif --} -- --void help(void) --{ -- printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2005 Fabrice Bellard\n" -- "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" -- " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n" -- " [infile1 infile2...] [-run infile args...]\n" -- "\n" -- "General options:\n" -- " -v display current version\n" -- " -c compile only - generate an object file\n" -- " -o outfile set output filename\n" -- " -Bdir set tcc internal library path\n" -- " -bench output compilation statistics\n" -- " -run run compiled source\n" -- " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" -- " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" -- " -w disable all warnings\n" -- "Preprocessor options:\n" -- " -Idir add include path 'dir'\n" -- " -Dsym[=val] define 'sym' with value 'val'\n" -- " -Usym undefine 'sym'\n" -- "Linker options:\n" -- " -Ldir add library path 'dir'\n" -- " -llib link with dynamic or static library 'lib'\n" -- " -shared generate a shared library\n" -- " -static static linking\n" -- " -rdynamic export all global symbols to dynamic linker\n" -- " -r relocatable output\n" -- "Debugger options:\n" -- " -g generate runtime debug info\n" --#ifdef CONFIG_TCC_BCHECK -- " -b compile with built-in memory and bounds checker (implies -g)\n" --#endif -- " -bt N show N callers in stack traces\n" -- ); --} -- --#define TCC_OPTION_HAS_ARG 0x0001 --#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ -- --typedef struct TCCOption { -- const char *name; -- uint16_t index; -- uint16_t flags; --} TCCOption; -- --enum { -- TCC_OPTION_HELP, -- TCC_OPTION_I, -- TCC_OPTION_D, -- TCC_OPTION_U, -- TCC_OPTION_L, -- TCC_OPTION_B, -- TCC_OPTION_l, -- TCC_OPTION_bench, -- TCC_OPTION_bt, -- TCC_OPTION_b, -- TCC_OPTION_g, -- TCC_OPTION_c, -- TCC_OPTION_static, -- TCC_OPTION_shared, -- TCC_OPTION_o, -- TCC_OPTION_r, -- TCC_OPTION_Wl, -- TCC_OPTION_W, -- TCC_OPTION_O, -- TCC_OPTION_m, -- TCC_OPTION_f, -- TCC_OPTION_nostdinc, -- TCC_OPTION_nostdlib, -- TCC_OPTION_print_search_dirs, -- TCC_OPTION_rdynamic, -- TCC_OPTION_run, -- TCC_OPTION_v, -- TCC_OPTION_w, -- TCC_OPTION_pipe, --}; -- --static const TCCOption tcc_options[] = { -- { "h", TCC_OPTION_HELP, 0 }, -- { "?", TCC_OPTION_HELP, 0 }, -- { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, -- { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, -- { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, -- { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, -- { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, -- { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "bench", TCC_OPTION_bench, 0 }, -- { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, --#ifdef CONFIG_TCC_BCHECK -- { "b", TCC_OPTION_b, 0 }, --#endif -- { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "c", TCC_OPTION_c, 0 }, -- { "static", TCC_OPTION_static, 0 }, -- { "shared", TCC_OPTION_shared, 0 }, -- { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, -- { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "rdynamic", TCC_OPTION_rdynamic, 0 }, -- { "r", TCC_OPTION_r, 0 }, -- { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, -- { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, -- { "nostdinc", TCC_OPTION_nostdinc, 0 }, -- { "nostdlib", TCC_OPTION_nostdlib, 0 }, -- { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, -- { "v", TCC_OPTION_v, 0 }, -- { "w", TCC_OPTION_w, 0 }, -- { "pipe", TCC_OPTION_pipe, 0}, -- { NULL }, --}; -- --/* convert 'str' into an array of space separated strings */ --static int expand_args(char ***pargv, const char *str) --{ -- const char *s1; -- char **argv, *arg; -- int argc, len; -- -- argc = 0; -- argv = NULL; -- for(;;) { -- while (is_space(*str)) -- str++; -- if (*str == '\0') -- break; -- s1 = str; -- while (*str != '\0' && !is_space(*str)) -- str++; -- len = str - s1; -- arg = tcc_malloc(len + 1); -- memcpy(arg, s1, len); -- arg[len] = '\0'; -- dynarray_add((void ***)&argv, &argc, arg); -- } -- *pargv = argv; -- return argc; --} -- --static char **files; --static int nb_files, nb_libraries; --static int multiple_files; --static int print_search_dirs; --static int output_type; --static int reloc_output; --static const char *outfile; -- --int parse_args(TCCState *s, int argc, char **argv) --{ -- int optind; -- const TCCOption *popt; -- const char *optarg, *p1, *r1; -- char *r; -- -- optind = 0; -- while (1) { -- if (optind >= argc) { -- if (nb_files == 0 && !print_search_dirs) -- goto show_help; -- else -- break; -- } -- r = argv[optind++]; -- if (r[0] != '-') { -- /* add a new file */ -- dynarray_add((void ***)&files, &nb_files, r); -- if (!multiple_files) { -- optind--; -- /* argv[0] will be this file */ -- break; -- } -- } else { -- /* find option in table (match only the first chars */ -- popt = tcc_options; -- for(;;) { -- p1 = popt->name; -- if (p1 == NULL) -- error("invalid option -- '%s'", r); -- r1 = r + 1; -- for(;;) { -- if (*p1 == '\0') -- goto option_found; -- if (*r1 != *p1) -- break; -- p1++; -- r1++; -- } -- popt++; -- } -- option_found: -- if (popt->flags & TCC_OPTION_HAS_ARG) { -- if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) { -- optarg = r1; -- } else { -- if (optind >= argc) -- error("argument to '%s' is missing", r); -- optarg = argv[optind++]; -- } -- } else { -- if (*r1 != '\0') -- goto show_help; -- optarg = NULL; -- } -- -- switch(popt->index) { -- case TCC_OPTION_HELP: -- show_help: -- help(); -- exit(1); -- case TCC_OPTION_I: -- if (tcc_add_include_path(s, optarg) < 0) -- error("too many include paths"); -- break; -- case TCC_OPTION_D: -- { -- char *sym, *value; -- sym = (char *)optarg; -- value = strchr(sym, '='); -- if (value) { -- *value = '\0'; -- value++; -- } -- tcc_define_symbol(s, sym, value); -- } -- break; -- case TCC_OPTION_U: -- tcc_undefine_symbol(s, optarg); -- break; -- case TCC_OPTION_L: -- tcc_add_library_path(s, optarg); -- break; -- case TCC_OPTION_B: -- /* set tcc utilities path (mainly for tcc development) */ -- tcc_lib_path = optarg; -- break; -- case TCC_OPTION_l: -- dynarray_add((void ***)&files, &nb_files, r); -- nb_libraries++; -- break; -- case TCC_OPTION_bench: -- do_bench = 1; -- break; -- case TCC_OPTION_bt: -- num_callers = atoi(optarg); -- break; --#ifdef CONFIG_TCC_BCHECK -- case TCC_OPTION_b: -- do_bounds_check = 1; -- do_debug = 1; -- break; --#endif -- case TCC_OPTION_g: -- do_debug = 1; -- break; -- case TCC_OPTION_c: -- multiple_files = 1; -- output_type = TCC_OUTPUT_OBJ; -- break; -- case TCC_OPTION_static: -- s->static_link = 1; -- break; -- case TCC_OPTION_shared: -- output_type = TCC_OUTPUT_DLL; -- break; -- case TCC_OPTION_o: -- multiple_files = 1; -- outfile = optarg; -- break; -- case TCC_OPTION_r: -- /* generate a .o merging several output files */ -- reloc_output = 1; -- output_type = TCC_OUTPUT_OBJ; -- break; -- case TCC_OPTION_nostdinc: -- s->nostdinc = 1; -- break; -- case TCC_OPTION_nostdlib: -- s->nostdlib = 1; -- break; -- case TCC_OPTION_print_search_dirs: -- print_search_dirs = 1; -- break; -- case TCC_OPTION_run: -- { -- int argc1; -- char **argv1; -- argc1 = expand_args(&argv1, optarg); -- if (argc1 > 0) { -- parse_args(s, argc1, argv1); -- } -- multiple_files = 0; -- output_type = TCC_OUTPUT_MEMORY; -- } -- break; -- case TCC_OPTION_v: -- printf("tcc version %s\n", TCC_VERSION); -- exit(0); -- case TCC_OPTION_f: -- if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) -- goto unsupported_option; -- break; -- case TCC_OPTION_W: -- if (tcc_set_warning(s, optarg, 1) < 0 && -- s->warn_unsupported) -- goto unsupported_option; -- break; -- case TCC_OPTION_w: -- s->warn_none = 1; -- break; -- case TCC_OPTION_rdynamic: -- s->rdynamic = 1; -- break; -- case TCC_OPTION_Wl: -- { -- const char *p; -- if (strstart(optarg, "-Ttext,", &p)) { -- s->text_addr = strtoul(p, NULL, 16); -- s->has_text_addr = 1; -- } else if (strstart(optarg, "--oformat,", &p)) { -- if (strstart(p, "elf32-", NULL)) { -- s->output_format = TCC_OUTPUT_FORMAT_ELF; -- } else if (!strcmp(p, "binary")) { -- s->output_format = TCC_OUTPUT_FORMAT_BINARY; -- } else --#ifdef TCC_TARGET_COFF -- if (!strcmp(p, "coff")) { -- s->output_format = TCC_OUTPUT_FORMAT_COFF; -- } else --#endif -- { -- error("target %s not found", p); -- } -- } else { -- error("unsupported linker option '%s'", optarg); -- } -- } -- break; -- default: -- if (s->warn_unsupported) { -- unsupported_option: -- warning("unsupported option '%s'", r); -- } -- break; -- } -- } -- } -- return optind; --} -- --int main(int argc, char **argv) --{ -- int i; -- TCCState *s; -- int nb_objfiles, ret, optind; -- char objfilename[1024]; -- int64_t start_time = 0; -- --#ifdef WIN32 -- /* on win32, we suppose the lib and includes are at the location -- of 'tcc.exe' */ -- { -- static char path[1024]; -- char *p, *d; -- -- GetModuleFileNameA(NULL, path, sizeof path); -- p = d = strlwr(path); -- while (*d) -- { -- if (*d == '\\') *d = '/', p = d; -- ++d; -- } -- *p = '\0'; -- tcc_lib_path = path; -- } --#endif -- -- s = tcc_new(); -- output_type = TCC_OUTPUT_EXE; -- outfile = NULL; -- multiple_files = 1; -- files = NULL; -- nb_files = 0; -- nb_libraries = 0; -- reloc_output = 0; -- print_search_dirs = 0; -- -- optind = parse_args(s, argc - 1, argv + 1) + 1; -- -- if (print_search_dirs) { -- /* enough for Linux kernel */ -- printf("install: %s/\n", tcc_lib_path); -- return 0; -- } -- -- nb_objfiles = nb_files - nb_libraries; -- -- /* if outfile provided without other options, we output an -- executable */ -- if (outfile && output_type == TCC_OUTPUT_MEMORY) -- output_type = TCC_OUTPUT_EXE; -- -- /* check -c consistency : only single file handled. XXX: checks file type */ -- if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { -- /* accepts only a single input file */ -- if (nb_objfiles != 1) -- error("cannot specify multiple files with -c"); -- if (nb_libraries != 0) -- error("cannot specify libraries with -c"); -- } -- -- if (output_type != TCC_OUTPUT_MEMORY) { -- if (!outfile) { -- /* compute default outfile name */ -- pstrcpy(objfilename, sizeof(objfilename) - 1, -- /* strip path */ -- tcc_basename(files[0])); --#ifdef TCC_TARGET_PE -- pe_guess_outfile(objfilename, output_type); --#else -- if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { -- char *ext = strrchr(objfilename, '.'); -- if (!ext) -- goto default_outfile; -- /* add .o extension */ -- strcpy(ext + 1, "o"); -- } else { -- default_outfile: -- pstrcpy(objfilename, sizeof(objfilename), "a.out"); -- } --#endif -- outfile = objfilename; -- } -- } -- -- if (do_bench) { -- start_time = getclock_us(); -- } -- -- tcc_set_output_type(s, output_type); -- -- /* compile or add each files or library */ -- for(i = 0;i < nb_files; i++) { -- const char *filename; -- -- filename = files[i]; -- if (filename[0] == '-') { -- if (tcc_add_library(s, filename + 2) < 0) -- error("cannot find %s", filename); -- } else { -- if (tcc_add_file(s, filename) < 0) { -- ret = 1; -- goto the_end; -- } -- } -- } -- -- /* free all files */ -- tcc_free(files); -- -- if (do_bench) { -- double total_time; -- total_time = (double)(getclock_us() - start_time) / 1000000.0; -- if (total_time < 0.001) -- total_time = 0.001; -- if (total_bytes < 1) -- total_bytes = 1; -- printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", -- tok_ident - TOK_IDENT, total_lines, total_bytes, -- total_time, (int)(total_lines / total_time), -- total_bytes / total_time / 1000000.0); -- } -- -- if (s->output_type == TCC_OUTPUT_MEMORY) { -- ret = tcc_run(s, argc - optind, argv + optind); -- } else --#ifdef TCC_TARGET_PE -- if (s->output_type != TCC_OUTPUT_OBJ) { -- ret = tcc_output_pe(s, outfile); -- } else --#endif -- { -- tcc_output_file(s, outfile); -- ret = 0; -- } -- the_end: -- /* XXX: cannot do it with bound checking because of the malloc hooks */ -- if (!do_bounds_check) -- tcc_delete(s); -- --#ifdef MEM_DEBUG -- if (do_bench) { -- printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size); -- } --#endif -- return ret; --} -- --#endif -+#include "tcltcc.c" ---- tcc-0.9.24/tcccoff.c 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/tcccoff.c 2007-11-07 10:04:32.000000000 -0500 -@@ -1,5 +1,5 @@ - /* -- * COFF file handling for TCC -+ * COFF file handling for TCC (Needed for c67 target) - * - * Copyright (c) 2003, 2004 TK - * Copyright (c) 2004 Fabrice Bellard -@@ -107,7 +107,7 @@ - o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */ - - -- // create all the section headers -+ /* create all the section headers */ - - file_pointer = FILHSZ + sizeof(AOUTHDR); - -@@ -121,7 +121,7 @@ - NSectionsToOutput++; - - if (CoffTextSectionNo == -1 && tcc_sect == stext) -- CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is -+ CoffTextSectionNo = NSectionsToOutput; /* rem which coff sect number the .text sect is */ - - strcpy(coff_sec->s_name, tcc_sect->name); /* section name */ - -@@ -142,8 +142,8 @@ - - file_hdr.f_nscns = NSectionsToOutput; /* number of sections */ - -- // now loop through and determine file pointer locations -- // for the raw data -+ /* now loop through and determine file pointer locations */ -+ /* for the raw data */ - - - for (i = 1; i < s1->nb_sections; i++) { -@@ -151,21 +151,21 @@ - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { -- // put raw data -+ /* put raw data */ - coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */ - file_pointer += coff_sec->s_size; - } - } - -- // now loop through and determine file pointer locations -- // for the relocation data -+ /* now loop through and determine file pointer locations */ -+ /* for the relocation data */ - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { -- // put relocations data -+ /* put relocations data */ - if (coff_sec->s_nreloc > 0) { - coff_sec->s_relptr = file_pointer; /* file ptr to relocation */ - file_pointer += coff_sec->s_nreloc * sizeof(struct reloc); -@@ -173,8 +173,8 @@ - } - } - -- // now loop through and determine file pointer locations -- // for the line number data -+ /* now loop through and determine file pointer locations */ -+ /* for the line number data */ - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; -@@ -184,10 +184,10 @@ - coff_sec->s_lnnoptr = 0; - - if (do_debug && tcc_sect == stext) { -- // count how many line nos data -+ /* count how many line nos data */ - -- // also find association between source file name and function -- // so we can sort the symbol table -+ /* also find association between source file name and function */ -+ /* so we can sort the symbol table */ - - - Stab_Sym *sym, *sym_end; -@@ -218,7 +218,7 @@ - /* function start or end */ - case N_FUN: - if (sym->n_strx == 0) { -- // end of function -+ /* end of function */ - - coff_sec->s_nlnno++; - file_pointer += LINESZ; -@@ -232,7 +232,7 @@ - LineNoFilePtr[nFuncs]) / LINESZ - 1; - LastLineNo[nFuncs++] = last_line_num + 1; - } else { -- // beginning of function -+ /* beginning of function */ - - LineNoFilePtr[nFuncs] = file_pointer; - coff_sec->s_nlnno++; -@@ -255,7 +255,7 @@ - func_name[len] = '\0'; - } - -- // save the file that it came in so we can sort later -+ /* save the file that it came in so we can sort later */ - pstrcpy(AssociatedFile[nFuncs], sizeof(func_name), - incl_files[incl_index - 1]); - -@@ -318,13 +318,13 @@ - - file_pointer += file_hdr.f_nsyms * SYMNMLEN; - -- // OK now we are all set to write the file -+ /* OK now we are all set to write the file */ - - - fwrite(&file_hdr, FILHSZ, 1, f); - fwrite(&o_filehdr, sizeof(o_filehdr), 1, f); - -- // write section headers -+ /* write section headers */ - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; -@@ -334,7 +334,7 @@ - } - } - -- // write raw data -+ /* write raw data */ - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; -@@ -344,13 +344,13 @@ - } - } - -- // write relocation data -+ /* write relocation data */ - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (OutputTheSection(tcc_sect)) { -- // put relocations data -+ /* put relocations data */ - if (coff_sec->s_nreloc > 0) { - fwrite(tcc_sect->reloc, - coff_sec->s_nreloc * sizeof(struct reloc), 1, f); -@@ -359,20 +359,20 @@ - } - - -- // group the symbols in order of filename, func1, func2, etc -- // finally global symbols -+ /* group the symbols in order of filename, func1, func2, etc */ -+ /* finally global symbols */ - - if (do_debug) - SortSymbolTable(); - -- // write line no data -+ /* write line no data */ - - for (i = 1; i < s1->nb_sections; i++) { - coff_sec = §ion_header[i]; - tcc_sect = s1->sections[i]; - - if (do_debug && tcc_sect == stext) { -- // count how many line nos data -+ /* count how many line nos data */ - - - Stab_Sym *sym, *sym_end; -@@ -400,7 +400,7 @@ - /* function start or end */ - case N_FUN: - if (sym->n_strx == 0) { -- // end of function -+ /* end of function */ - - CoffLineNo.l_addr.l_paddr = last_pc; - CoffLineNo.l_lnno = last_line_num + 1; -@@ -410,7 +410,7 @@ - func_name[0] = '\0'; - func_addr = 0; - } else { -- // beginning of function -+ /* beginning of function */ - - str = - (const char *) stabstr_section->data + -@@ -431,7 +431,7 @@ - last_pc = func_addr; - last_line_num = -1; - -- // output a function begin -+ /* output a function begin */ - - CoffLineNo.l_addr.l_symndx = - FindCoffSymbolIndex(func_name); -@@ -449,7 +449,7 @@ - /* XXX: slow! */ - strcpy(last_func_name, func_name); - -- // output a line reference -+ /* output a line reference */ - - CoffLineNo.l_addr.l_paddr = last_pc; - -@@ -498,7 +498,7 @@ - } - } - -- // write symbol table -+ /* write symbol table */ - if (do_debug) { - int k; - struct syment csym; -@@ -537,13 +537,13 @@ - pCoff_str_table - Coff_str_table + 4; - - strcpy(pCoff_str_table, name); -- pCoff_str_table += strlen(name) + 1; // skip over null -+ pCoff_str_table += strlen(name) + 1; /* skip over null */ - nstr++; - } - - if (p->st_info == 4) { -- // put a filename symbol -- csym.n_value = 33; // ????? -+ /* put a filename symbol */ -+ csym.n_value = 33; /* ????? */ - csym.n_scnum = N_DEBUG; - csym.n_type = 0; - csym.n_sclass = C_FILE; -@@ -552,7 +552,7 @@ - n++; - - } else if (p->st_info == 0x12) { -- // find the function data -+ /* find the function data */ - - for (k = 0; k < nFuncs; k++) { - if (strcmp(name, Func[k]) == 0) -@@ -566,35 +566,35 @@ - - error(s); - } -- // put a Function Name -+ /* put a Function Name */ - -- csym.n_value = p->st_value; // physical address -+ csym.n_value = p->st_value; /* physical address */ - csym.n_scnum = CoffTextSectionNo; - csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0); - csym.n_sclass = C_EXT; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - -- // now put aux info -+ /* now put aux info */ - - auxfunc.tag = 0; - auxfunc.size = EndAddress[k] - p->st_value; - auxfunc.fileptr = LineNoFilePtr[k]; -- auxfunc.nextsym = n + 6; // tktk -+ auxfunc.nextsym = n + 6; /* tktk */ - auxfunc.dummy = 0; - fwrite(&auxfunc, 18, 1, f); - -- // put a .bf -+ /* put a .bf */ - - strcpy(csym._n._n_name, ".bf"); -- csym.n_value = p->st_value; // physical address -+ csym.n_value = p->st_value; /* physical address */ - csym.n_scnum = CoffTextSectionNo; - csym.n_type = 0; - csym.n_sclass = C_FCN; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - -- // now put aux info -+ /* now put aux info */ - - auxbf.regmask = 0; - auxbf.lineno = 0; -@@ -604,17 +604,17 @@ - auxbf.dummy = 0; - fwrite(&auxbf, 18, 1, f); - -- // put a .ef -+ /* put a .ef */ - - strcpy(csym._n._n_name, ".ef"); -- csym.n_value = EndAddress[k]; // physical address -+ csym.n_value = EndAddress[k]; /* physical address */ - csym.n_scnum = CoffTextSectionNo; - csym.n_type = 0; - csym.n_sclass = C_FCN; - csym.n_numaux = 1; - fwrite(&csym, 18, 1, f); - -- // now put aux info -+ /* now put aux info */ - - auxef.dummy = 0; - auxef.lineno = LastLineNo[k]; -@@ -627,16 +627,16 @@ - n += 6; - - } else { -- // try an put some type info -+ /* try an put some type info */ - - if ((p->st_other & VT_BTYPE) == VT_DOUBLE) { -- csym.n_type = T_DOUBLE; // int -+ csym.n_type = T_DOUBLE; /* int */ - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) { - csym.n_type = T_FLOAT; - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_INT) { -- csym.n_type = T_INT; // int -+ csym.n_type = T_INT; /* int */ - csym.n_sclass = C_EXT; - } else if ((p->st_other & VT_BTYPE) == VT_SHORT) { - csym.n_type = T_SHORT; -@@ -645,7 +645,7 @@ - csym.n_type = T_CHAR; - csym.n_sclass = C_EXT; - } else { -- csym.n_type = T_INT; // just mark as a label -+ csym.n_type = T_INT; /* just mark as a label */ - csym.n_sclass = C_LABEL; - } - -@@ -671,16 +671,16 @@ - } - - if (do_debug) { -- // write string table -+ /* write string table */ - -- // first write the size -+ /* first write the size */ - i = pCoff_str_table - Coff_str_table; - fwrite(&i, 4, 1, f); - -- // then write the strings -+ /* then write the strings */ - fwrite(Coff_str_table, i, 1, f); - -- tcc_free(Coff_str_table); -+ free(Coff_str_table); - } - - return 0; -@@ -688,8 +688,8 @@ - - - --// group the symbols in order of filename, func1, func2, etc --// finally global symbols -+/* group the symbols in order of filename, func1, func2, etc */ -+/* finally global symbols */ - - void SortSymbolTable(void) - { -@@ -702,15 +702,15 @@ - p = (Elf32_Sym *) symtab_section->data; - - -- // find a file symbol, copy it over -- // then scan the whole symbol list and copy any function -- // symbols that match the file association -+ /* find a file symbol, copy it over */ -+ /* then scan the whole symbol list and copy any function */ -+ /* symbols that match the file association */ - - for (i = 0; i < nb_syms; i++) { - if (p->st_info == 4) { - name = (char *) symtab_section->link->data + p->st_name; - -- // this is a file symbol, copy it over -+ /* this is a file symbol, copy it over */ - - NewTable[n++] = *p; - -@@ -718,12 +718,12 @@ - - for (j = 0; j < nb_syms; j++) { - if (p2->st_info == 0x12) { -- // this is a func symbol -+ /* this is a func symbol */ - - name2 = - (char *) symtab_section->link->data + p2->st_name; - -- // find the function data index -+ /* find the function data index */ - - for (k = 0; k < nFuncs; k++) { - if (strcmp(name2, Func[k]) == 0) -@@ -741,7 +741,7 @@ - } - - if (strcmp(AssociatedFile[k], name) == 0) { -- // yes they match copy it over -+ /* yes they match copy it over */ - - NewTable[n++] = *p2; - } -@@ -752,8 +752,8 @@ - p++; - } - -- // now all the filename and func symbols should have been copied over -- // copy all the rest over (all except file and funcs) -+ /* now all the filename and func symbols should have been copied over */ -+ /* copy all the rest over (all except file and funcs) */ - - p = (Elf32_Sym *) symtab_section->data; - for (i = 0; i < nb_syms; i++) { -@@ -766,14 +766,14 @@ - if (n != nb_syms) - error("Internal Compiler error, debug info"); - -- // copy it all back -+ /* copy it all back */ - - p = (Elf32_Sym *) symtab_section->data; - for (i = 0; i < nb_syms; i++) { - *p++ = NewTable[i]; - } - -- tcc_free(NewTable); -+ free(NewTable); - } - - -@@ -790,7 +790,7 @@ - name = (char *) symtab_section->link->data + p->st_name; - - if (p->st_info == 4) { -- // put a filename symbol -+ /* put a filename symbol */ - n++; - } else if (p->st_info == 0x12) { - -@@ -799,17 +799,17 @@ - - n += 6; - -- // put a Function Name -+ /* put a Function Name */ - -- // now put aux info -+ /* now put aux info */ - -- // put a .bf -+ /* put a .bf */ - -- // now put aux info -+ /* now put aux info */ - -- // put a .ef -+ /* put a .ef */ - -- // now put aux info -+ /* now put aux info */ - - } else { - n += 2; -@@ -818,7 +818,7 @@ - p++; - } - -- return n; // total number of symbols -+ return n; /* total number of symbols */ - } - - BOOL OutputTheSection(Section * sect) -@@ -867,7 +867,7 @@ - - int tcc_load_coff(TCCState * s1, int fd) - { --// tktk TokenSym *ts; -+/* tktk TokenSym *ts; */ - - FILE *f; - unsigned int str_size; -@@ -888,7 +888,7 @@ - if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1) - error("error reading .out file for input"); - -- // first read the string table -+ /* first read the string table */ - - if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET)) - error("error reading .out file for input"); -@@ -902,9 +902,9 @@ - if (fread(Coff_str_table, str_size - 4, 1, f) != 1) - error("error reading .out file for input"); - -- // read/process all the symbols -+ /* read/process all the symbols */ - -- // seek back to symbols -+ /* seek back to symbols */ - - if (fseek(f, file_hdr.f_symptr, SEEK_SET)) - error("error reading .out file for input"); -@@ -927,22 +927,22 @@ - name = name2; - } - } --// if (strcmp("_DAC_Buffer",name)==0) // tktk --// name[0]=0; -+/* if (strcmp("_DAC_Buffer",name)==0) // tktk */ -+/* name[0]=0; */ - -- if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures -- (csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure -- (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles -- (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats -+ if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || /* structures */ -+ (csym.n_type == 0x18 && csym.n_sclass == 0x2) || /* pointer to structure */ -+ (csym.n_type == 0x7 && csym.n_sclass == 0x2) || /* doubles */ -+ (csym.n_type == 0x6 && csym.n_sclass == 0x2)) /* floats */ - { -- // strip off any leading underscore (except for other main routine) -+ /* strip off any leading underscore (except for other main routine) */ - - if (name[0] == '_' && strcmp(name, "_main") != 0) - name++; - - tcc_add_symbol(s1, name, csym.n_value); - } -- // skip any aux records -+ /* skip any aux records */ - - if (csym.n_numaux == 1) { - if (fread(&csym, SYMESZ, 1, f) != 1) ---- tcc-0.9.23/tcc-doc.texi 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/tcc-doc.texi 2007-11-07 10:04:32.000000000 -0500 -@@ -123,10 +123,10 @@ - Scripting: - - TCC can be invoked from @emph{scripts}, just as shell scripts. You just --need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source: -+need to add @code{#!/usr/bin/tcc -run} at the start of your C source: - - @example --#!/usr/local/bin/tcc -run -+#!/usr/bin/tcc -run - #include - - int main() -@@ -173,7 +173,7 @@ - In a script, it gives the following header: - - @example --#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 -+#!/usr/bin/tcc -run -L/usr/X11R6/lib -lX11 - #include - int main(int argc, char **argv) - @{ ---- tcc-0.9.24/tccelf.c 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/tccelf.c 2007-11-07 10:04:32.000000000 -0500 -@@ -18,14 +18,16 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - --static int put_elf_str(Section *s, const char *sym) -+#include -+ -+static int put_elf_str(TCCState *st, Section *s, const char *sym) - { - int offset, len; - char *ptr; - - len = strlen(sym) + 1; - offset = s->data_offset; -- ptr = section_ptr_add(s, len); -+ ptr = section_ptr_add(st, s, len); - memcpy(ptr, sym, len); - return offset; - } -@@ -47,7 +49,7 @@ - - /* rebuild hash table of section s */ - /* NOTE: we do factorize the hash table code to go faster */ --static void rebuild_hash(Section *s, unsigned int nb_buckets) -+static void rebuild_hash(TCCState *st, Section *s, unsigned int nb_buckets) - { - Elf32_Sym *sym; - int *ptr, *hash, nb_syms, sym_index, h; -@@ -57,7 +59,7 @@ - nb_syms = s->data_offset / sizeof(Elf32_Sym); - - s->hash->data_offset = 0; -- ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int)); -+ ptr = section_ptr_add(st, s->hash, (2 + nb_buckets + nb_syms) * sizeof(int)); - ptr[0] = nb_buckets; - ptr[1] = nb_syms; - ptr += 2; -@@ -80,7 +82,8 @@ - } - - /* return the symbol number */ --static int put_elf_sym(Section *s, -+static int put_elf_sym(TCCState *st, -+ Section *s, - unsigned long value, unsigned long size, - int info, int other, int shndx, const char *name) - { -@@ -89,9 +92,9 @@ - Elf32_Sym *sym; - Section *hs; - -- sym = section_ptr_add(s, sizeof(Elf32_Sym)); -+ sym = section_ptr_add(st, s, sizeof(Elf32_Sym)); - if (name) -- name_offset = put_elf_str(s->link, name); -+ name_offset = put_elf_str(st, s->link, name); - else - name_offset = 0; - /* XXX: endianness */ -@@ -105,7 +108,7 @@ - hs = s->hash; - if (hs) { - int *ptr, *base; -- ptr = section_ptr_add(hs, sizeof(int)); -+ ptr = section_ptr_add(st, hs, sizeof(int)); - base = (int *)hs->data; - /* only add global or weak symbols */ - if (ELF32_ST_BIND(info) != STB_LOCAL) { -@@ -118,7 +121,7 @@ - /* we resize the hash table */ - hs->nb_hashed_syms++; - if (hs->nb_hashed_syms > 2 * nbuckets) { -- rebuild_hash(s, 2 * nbuckets); -+ rebuild_hash(st, s, 2 * nbuckets); - } - } else { - *ptr = 0; -@@ -154,7 +157,7 @@ - } - - /* return elf symbol value or error */ --int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name) -+int tcc_get_symbol(TCCState *st, unsigned long *pval, const char *name) - { - int sym_index; - Elf32_Sym *sym; -@@ -167,17 +170,17 @@ - return 0; - } - --void *tcc_get_symbol_err(TCCState *s, const char *name) -+void *tcc_get_symbol_err(TCCState *st, const char *name) - { - unsigned long val; -- if (tcc_get_symbol(s, &val, name) < 0) -- error("%s not defined", name); -+ if (tcc_get_symbol(st, &val, name) < 0) -+ tcc_error(st, "%s not defined", name); - return (void *)val; - } - - /* add an elf symbol : check if it is already defined and patch - it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ --static int add_elf_sym(Section *s, unsigned long value, unsigned long size, -+static int add_elf_sym(TCCState *st, Section *s, unsigned long value, unsigned long size, - int info, int other, int sh_num, const char *name) - { - Elf32_Sym *esym; -@@ -206,7 +209,7 @@ - } else { - new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis; - } -- esym->st_other = (esym->st_other & ~ELF32_ST_VISIBILITY(-1)) -+ esym->st_other = (esym->st_other & ~ELF32_ST_VISIBILITY(UCHAR_MAX)) - | new_vis; - other = esym->st_other; /* in case we have to patch esym */ - if (sh_num == SHN_UNDEF) { -@@ -219,18 +222,14 @@ - /* weak is ignored if already global */ - } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { - /* ignore hidden symbols after */ -- } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) { -- /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 -- No idea if this is the correct solution ... */ -- goto do_patch; -- } else if (s == tcc_state->dynsymtab_section) { -- /* we accept that two DLL define the same symbol */ - } else { --#if 1 -- printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", -- sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis); -+#if 0 -+ printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n", -+ sym_bind, sh_num, esym_bind, esym->st_shndx); - #endif -- error_noabort("'%s' defined twice", name); -+ /* NOTE: we accept that two DLL define the same symbol */ -+ if (s != st->dynsymtab_section) -+ error_noabort(st, "'%s' defined twice", name); - } - } else { - do_patch: -@@ -242,7 +241,7 @@ - } - } else { - do_def: -- sym_index = put_elf_sym(s, value, size, -+ sym_index = put_elf_sym(st, s, value, size, - ELF32_ST_INFO(sym_bind, sym_type), other, - sh_num, name); - } -@@ -250,7 +249,7 @@ - } - - /* put relocation */ --static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, -+static void put_elf_reloc(TCCState * st, Section *symtab, Section *s, unsigned long offset, - int type, int symbol) - { - char buf[256]; -@@ -263,13 +262,13 @@ - snprintf(buf, sizeof(buf), ".rel%s", s->name); - /* if the symtab is allocated, then we consider the relocation - are also */ -- sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags); -+ sr = new_section(st, buf, SHT_REL, symtab->sh_flags); - sr->sh_entsize = sizeof(Elf32_Rel); - sr->link = symtab; - sr->sh_info = s->sh_num; - s->reloc = sr; - } -- rel = section_ptr_add(sr, sizeof(Elf32_Rel)); -+ rel = section_ptr_add(st, sr, sizeof(Elf32_Rel)); - rel->r_offset = offset; - rel->r_info = ELF32_R_INFO(symbol, type); - } -@@ -284,14 +283,15 @@ - unsigned long n_value; /* value of symbol */ - } Stab_Sym; - --static void put_stabs(const char *str, int type, int other, int desc, -+static void put_stabs(TCCState *st, -+ const char *str, int type, int other, int desc, - unsigned long value) - { - Stab_Sym *sym; - -- sym = section_ptr_add(stab_section, sizeof(Stab_Sym)); -+ sym = section_ptr_add(st, stab_section, sizeof(Stab_Sym)); - if (str) { -- sym->n_strx = put_elf_str(stabstr_section, str); -+ sym->n_strx = put_elf_str(st, stabstr_section, str); - } else { - sym->n_strx = 0; - } -@@ -301,30 +301,31 @@ - sym->n_value = value; - } - --static void put_stabs_r(const char *str, int type, int other, int desc, -+static void put_stabs_r(TCCState *st, -+ const char *str, int type, int other, int desc, - unsigned long value, Section *sec, int sym_index) - { -- put_stabs(str, type, other, desc, value); -- put_elf_reloc(symtab_section, stab_section, -+ put_stabs(st, str, type, other, desc, value); -+ put_elf_reloc(st, symtab_section, stab_section, - stab_section->data_offset - sizeof(unsigned long), - R_DATA_32, sym_index); - } - --static void put_stabn(int type, int other, int desc, int value) -+static void put_stabn(TCCState *st, int type, int other, int desc, int value) - { -- put_stabs(NULL, type, other, desc, value); -+ put_stabs(st, NULL, type, other, desc, value); - } - --static void put_stabd(int type, int other, int desc) -+static void put_stabd(TCCState *st, int type, int other, int desc) - { -- put_stabs(NULL, type, other, desc, 0); -+ put_stabs(st, NULL, type, other, desc, 0); - } - - /* In an ELF file symbol table, the local symbols must appear below - the global and weak ones. Since TCC cannot sort it while generating - the code, we must do it after. All the relocation tables are also - modified to take into account the symbol table sorting */ --static void sort_syms(TCCState *s1, Section *s) -+static void sort_syms(TCCState *st, Section *s) - { - int *old_to_new_syms; - Elf32_Sym *new_syms; -@@ -335,8 +336,8 @@ - int type, sym_index; - - nb_syms = s->data_offset / sizeof(Elf32_Sym); -- new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym)); -- old_to_new_syms = tcc_malloc(nb_syms * sizeof(int)); -+ new_syms = tcc_malloc(st, nb_syms * sizeof(Elf32_Sym)); -+ old_to_new_syms = tcc_malloc(st, nb_syms * sizeof(int)); - - /* first pass for local symbols */ - p = (Elf32_Sym *)s->data; -@@ -363,11 +364,11 @@ - - /* we copy the new symbols to the old */ - memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym)); -- tcc_free(new_syms); -+ ckfree((char *)new_syms); - - /* now we modify all the relocations */ -- for(i = 1; i < s1->nb_sections; i++) { -- sr = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ sr = st->sections[i]; - if (sr->sh_type == SHT_REL && sr->link == s) { - rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); - for(rel = (Elf32_Rel *)sr->data; -@@ -381,7 +382,7 @@ - } - } - -- tcc_free(old_to_new_syms); -+ ckfree((char *)old_to_new_syms); - } - - /* relocate common symbols in the .bss section */ -@@ -409,7 +410,7 @@ - - /* relocate symbol table, resolve undefined symbols if do_resolve is - true and output error if undefined symbol. */ --static void relocate_syms(TCCState *s1, int do_resolve) -+static void relocate_syms(TCCState *st, int do_resolve) - { - Elf32_Sym *sym, *esym, *sym_end; - int sym_bind, sh_num, sym_index; -@@ -425,16 +426,16 @@ - name = strtab_section->data + sym->st_name; - if (do_resolve) { - name = symtab_section->link->data + sym->st_name; -- addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info)); -+ addr = (unsigned long)resolve_sym(st, name, ELF32_ST_TYPE(sym->st_info)); - if (addr) { - sym->st_value = addr; - goto found; - } -- } else if (s1->dynsym) { -+ } else if (st->dynsym) { - /* if dynamic symbol exist, then use it */ -- sym_index = find_elf_sym(s1->dynsym, name); -+ sym_index = find_elf_sym(st->dynsym, name); - if (sym_index) { -- esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index]; -+ esym = &((Elf32_Sym *)st->dynsym->data)[sym_index]; - sym->st_value = esym->st_value; - goto found; - } -@@ -449,18 +450,18 @@ - if (sym_bind == STB_WEAK) { - sym->st_value = 0; - } else { -- error_noabort("undefined symbol '%s'", name); -+ error_noabort(st, "undefined symbol '%s'", name); - } - } else if (sh_num < SHN_LORESERVE) { - /* add section base */ -- sym->st_value += s1->sections[sym->st_shndx]->sh_addr; -+ sym->st_value += st->sections[sym->st_shndx]->sh_addr; - } - found: ; - } - } - - /* relocate a given section (CPU dependent) */ --static void relocate_section(TCCState *s1, Section *s) -+static void relocate_section(TCCState *st, Section *s) - { - Section *sr; - Elf32_Rel *rel, *rel_end, *qrel; -@@ -490,8 +491,8 @@ - switch(type) { - #if defined(TCC_TARGET_I386) - case R_386_32: -- if (s1->output_type == TCC_OUTPUT_DLL) { -- esym_index = s1->symtab_to_dynsym[sym_index]; -+ if (st->output_type == TCC_OUTPUT_DLL) { -+ esym_index = st->symtab_to_dynsym[sym_index]; - qrel->r_offset = rel->r_offset; - if (esym_index) { - qrel->r_info = ELF32_R_INFO(esym_index, R_386_32); -@@ -505,9 +506,9 @@ - *(int *)ptr += val; - break; - case R_386_PC32: -- if (s1->output_type == TCC_OUTPUT_DLL) { -+ if (st->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ -- esym_index = s1->symtab_to_dynsym[sym_index]; -+ esym_index = st->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32); -@@ -525,14 +526,14 @@ - *(int *)ptr = val; - break; - case R_386_GOTPC: -- *(int *)ptr += s1->got->sh_addr - addr; -+ *(int *)ptr += st->got->sh_addr - addr; - break; - case R_386_GOTOFF: -- *(int *)ptr += val - s1->got->sh_addr; -+ *(int *)ptr += val - st->got->sh_addr; - break; - case R_386_GOT32: - /* we load the got offset */ -- *(int *)ptr += s1->got_offsets[sym_index]; -+ *(int *)ptr += st->got_offsets[sym_index]; - break; - #elif defined(TCC_TARGET_ARM) - case R_ARM_PC24: -@@ -548,7 +549,7 @@ - x *= 4; - x += val - addr; - if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) -- error("can't relocate value at %x",addr); -+ tcc_error(st, "can't relocate value at %x",addr); - x >>= 2; - x &= 0xffffff; - (*(int *)ptr) |= x; -@@ -562,21 +563,21 @@ - x = (x * 2) / 2; - x += val - addr; - if((x^(x>>1))&0x40000000) -- error("can't relocate value at %x",addr); -+ tcc_error(st, "can't relocate value at %x",addr); - (*(int *)ptr) |= x & 0x7fffffff; - } - case R_ARM_ABS32: - *(int *)ptr += val; - break; - case R_ARM_BASE_PREL: -- *(int *)ptr += s1->got->sh_addr - addr; -+ *(int *)ptr += st->got->sh_addr - addr; - break; - case R_ARM_GOTOFF32: -- *(int *)ptr += val - s1->got->sh_addr; -+ *(int *)ptr += val - st->got->sh_addr; - break; - case R_ARM_GOT_BREL: - /* we load the got offset */ -- *(int *)ptr += s1->got_offsets[sym_index]; -+ *(int *)ptr += st->got_offsets[sym_index]; - break; - case R_ARM_COPY: - break; -@@ -593,12 +594,12 @@ - uint32_t orig; - - /* put the low 16 bits of the absolute address */ -- // add to what is already there -+ /* add to what is already there */ - - orig = ((*(int *)(ptr )) >> 7) & 0xffff; - orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16; - -- //patch both at once - assumes always in pairs Low - High -+ /*patch both at once - assumes always in pairs Low - High */ - - *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7); - *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7); -@@ -617,16 +618,16 @@ - } - /* if the relocation is allocated, we change its symbol table */ - if (sr->sh_flags & SHF_ALLOC) -- sr->link = s1->dynsym; -+ sr->link = st->dynsym; - } - - /* relocate relocation table in 'sr' */ --static void relocate_rel(TCCState *s1, Section *sr) -+static void relocate_rel(TCCState *st, Section *sr) - { - Section *s; - Elf32_Rel *rel, *rel_end; - -- s = s1->sections[sr->sh_info]; -+ s = st->sections[sr->sh_info]; - rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); - for(rel = (Elf32_Rel *)sr->data; - rel < rel_end; -@@ -637,7 +638,7 @@ - - /* count the number of dynamic relocations so that we can reserve - their space */ --static int prepare_dynamic_rel(TCCState *s1, Section *sr) -+static int prepare_dynamic_rel(TCCState *st, Section *sr) - { - Elf32_Rel *rel, *rel_end; - int sym_index, esym_index, type, count; -@@ -652,7 +653,7 @@ - count++; - break; - case R_386_PC32: -- esym_index = s1->symtab_to_dynsym[sym_index]; -+ esym_index = st->symtab_to_dynsym[sym_index]; - if (esym_index) - count++; - break; -@@ -668,25 +669,25 @@ - return count; - } - --static void put_got_offset(TCCState *s1, int index, unsigned long val) -+static void put_got_offset(TCCState *st, int index, unsigned long val) - { - int n; - unsigned long *tab; - -- if (index >= s1->nb_got_offsets) { -+ if (index >= st->nb_got_offsets) { - /* find immediately bigger power of 2 and reallocate array */ - n = 1; - while (index >= n) - n *= 2; -- tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long)); -+ tab = tcc_realloc(st, st->got_offsets, n * sizeof(unsigned long)); - if (!tab) -- error("memory full"); -- s1->got_offsets = tab; -- memset(s1->got_offsets + s1->nb_got_offsets, 0, -- (n - s1->nb_got_offsets) * sizeof(unsigned long)); -- s1->nb_got_offsets = n; -+ tcc_error(st, "memory full"); -+ st->got_offsets = tab; -+ memset(st->got_offsets + st->nb_got_offsets, 0, -+ (n - st->nb_got_offsets) * sizeof(unsigned long)); -+ st->nb_got_offsets = n; - } -- s1->got_offsets[index] = val; -+ st->got_offsets[index] = val; - } - - /* XXX: suppress that */ -@@ -705,16 +706,16 @@ - } - #endif - --static void build_got(TCCState *s1) -+static void build_got(TCCState *st) - { - unsigned char *ptr; - - /* if no got, then create it */ -- s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); -- s1->got->sh_entsize = 4; -- add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), -- 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); -- ptr = section_ptr_add(s1->got, 3 * sizeof(int)); -+ st->got = new_section(st, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); -+ st->got->sh_entsize = 4; -+ add_elf_sym(st, symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), -+ 0, st->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); -+ ptr = section_ptr_add(st, st->got, 3 * sizeof(int)); - /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); - /* two dummy got entries */ -@@ -724,7 +725,7 @@ - - /* put a got entry corresponding to a symbol in symtab_section. 'size' - and 'info' can be modifed if more precise info comes from the DLL */ --static void put_got_entry(TCCState *s1, -+static void put_got_entry(TCCState *st, - int reloc_type, unsigned long size, int info, - int sym_index) - { -@@ -734,17 +735,17 @@ - unsigned long offset; - int *ptr; - -- if (!s1->got) -- build_got(s1); -+ if (!st->got) -+ build_got(st); - - /* if a got entry already exists for that symbol, no need to add one */ -- if (sym_index < s1->nb_got_offsets && -- s1->got_offsets[sym_index] != 0) -+ if (sym_index < st->nb_got_offsets && -+ st->got_offsets[sym_index] != 0) - return; - -- put_got_offset(s1, sym_index, s1->got->data_offset); -+ put_got_offset(st, sym_index, st->got->data_offset); - -- if (s1->dynsym) { -+ if (st->dynsym) { - sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; - name = symtab_section->link->data + sym->st_name; - offset = sym->st_value; -@@ -755,16 +756,16 @@ - int modrm; - - /* if we build a DLL, we add a %ebx offset */ -- if (s1->output_type == TCC_OUTPUT_DLL) -+ if (st->output_type == TCC_OUTPUT_DLL) - modrm = 0xa3; - else - modrm = 0x25; - - /* add a PLT entry */ -- plt = s1->plt; -+ plt = st->plt; - if (plt->data_offset == 0) { - /* first plt entry */ -- p = section_ptr_add(plt, 16); -+ p = section_ptr_add(st, plt, 16); - p[0] = 0xff; /* pushl got + 4 */ - p[1] = modrm + 0x10; - put32(p + 2, 4); -@@ -773,10 +774,10 @@ - put32(p + 8, 8); - } - -- p = section_ptr_add(plt, 16); -+ p = section_ptr_add(st, plt, 16); - p[0] = 0xff; /* jmp *(got + x) */ - p[1] = modrm; -- put32(p + 2, s1->got->data_offset); -+ put32(p + 2, st->got->data_offset); - p[6] = 0x68; /* push $xxx */ - put32(p + 7, (plt->data_offset - 32) >> 1); - p[11] = 0xe9; /* jmp plt_start */ -@@ -784,7 +785,7 @@ - - /* the symbol is modified so that it will be relocated to - the PLT */ -- if (s1->output_type == TCC_OUTPUT_EXE) -+ if (st->output_type == TCC_OUTPUT_EXE) - offset = plt->data_offset - 16; - } - #elif defined(TCC_TARGET_ARM) -@@ -793,57 +794,57 @@ - uint8_t *p; - - /* if we build a DLL, we add a %ebx offset */ -- if (s1->output_type == TCC_OUTPUT_DLL) -- error("DLLs unimplemented!"); -+ if (st->output_type == TCC_OUTPUT_DLL) -+ tcc_error(st, "DLLs unimplemented!"); - - /* add a PLT entry */ -- plt = s1->plt; -+ plt = st->plt; - if (plt->data_offset == 0) { - /* first plt entry */ -- p = section_ptr_add(plt, 16); -+ p = section_ptr_add(st, plt, 16); - put32(p , 0xe52de004); - put32(p + 4, 0xe59fe010); - put32(p + 8, 0xe08fe00e); - put32(p + 12, 0xe5bef008); - } - -- p = section_ptr_add(plt, 16); -+ p = section_ptr_add(st, plt, 16); - put32(p , 0xe59fc004); - put32(p+4, 0xe08fc00c); - put32(p+8, 0xe59cf000); -- put32(p+12, s1->got->data_offset); -+ put32(p+12, st->got->data_offset); - - /* the symbol is modified so that it will be relocated to - the PLT */ -- if (s1->output_type == TCC_OUTPUT_EXE) -+ if (st->output_type == TCC_OUTPUT_EXE) - offset = plt->data_offset - 16; - } - #elif defined(TCC_TARGET_C67) -- error("C67 got not implemented"); -+ tcc_error(st, "C67 got not implemented"); - #else - #error unsupported CPU - #endif -- index = put_elf_sym(s1->dynsym, offset, -+ index = put_elf_sym(st, st->dynsym, offset, - size, info, 0, sym->st_shndx, name); - /* put a got entry */ -- put_elf_reloc(s1->dynsym, s1->got, -- s1->got->data_offset, -+ put_elf_reloc(st, st->dynsym, st->got, -+ st->got->data_offset, - reloc_type, index); - } -- ptr = section_ptr_add(s1->got, sizeof(int)); -+ ptr = section_ptr_add(st, st->got, sizeof(int)); - *ptr = 0; - } - - /* build GOT and PLT entries */ --static void build_got_entries(TCCState *s1) -+static void build_got_entries(TCCState *st) - { - Section *s, *symtab; - Elf32_Rel *rel, *rel_end; - Elf32_Sym *sym; - int i, type, reloc_type, sym_index; - -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - if (s->sh_type != SHT_REL) - continue; - /* no need to handle got relocations */ -@@ -861,8 +862,8 @@ - case R_386_GOTOFF: - case R_386_GOTPC: - case R_386_PLT32: -- if (!s1->got) -- build_got(s1); -+ if (!st->got) -+ build_got(st); - if (type == R_386_GOT32 || type == R_386_PLT32) { - sym_index = ELF32_R_SYM(rel->r_info); - sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; -@@ -871,7 +872,7 @@ - reloc_type = R_386_GLOB_DAT; - else - reloc_type = R_386_JMP_SLOT; -- put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, -+ put_got_entry(st, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -@@ -880,8 +881,8 @@ - case R_ARM_GOTOFF32: - case R_ARM_BASE_PREL: - case R_ARM_PLT32: -- if (!s1->got) -- build_got(s1); -+ if (!st->got) -+ build_got(st); - if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) { - sym_index = ELF32_R_SYM(rel->r_info); - sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; -@@ -890,7 +891,7 @@ - reloc_type = R_ARM_GLOB_DAT; - else - reloc_type = R_ARM_JUMP_SLOT; -- put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, -+ put_got_entry(st, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -@@ -899,8 +900,8 @@ - case R_C60_GOTOFF: - case R_C60_GOTPC: - case R_C60_PLT32: -- if (!s1->got) -- build_got(s1); -+ if (!st->got) -+ build_got(st); - if (type == R_C60_GOT32 || type == R_C60_PLT32) { - sym_index = ELF32_R_SYM(rel->r_info); - sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; -@@ -909,7 +910,7 @@ - reloc_type = R_C60_GLOB_DAT; - else - reloc_type = R_C60_JMP_SLOT; -- put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, -+ put_got_entry(st, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -@@ -923,7 +924,7 @@ - } - } - --static Section *new_symtab(TCCState *s1, -+static Section *new_symtab(TCCState *st, - const char *symtab_name, int sh_type, int sh_flags, - const char *strtab_name, - const char *hash_name, int hash_sh_flags) -@@ -931,21 +932,21 @@ - Section *symtab, *strtab, *hash; - int *ptr, nb_buckets; - -- symtab = new_section(s1, symtab_name, sh_type, sh_flags); -+ symtab = new_section(st, symtab_name, sh_type, sh_flags); - symtab->sh_entsize = sizeof(Elf32_Sym); -- strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); -- put_elf_str(strtab, ""); -+ strtab = new_section(st, strtab_name, SHT_STRTAB, sh_flags); -+ put_elf_str(st, strtab, ""); - symtab->link = strtab; -- put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); -+ put_elf_sym(st, symtab, 0, 0, 0, 0, 0, NULL); - - nb_buckets = 1; - -- hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); -+ hash = new_section(st, hash_name, SHT_HASH, hash_sh_flags); - hash->sh_entsize = sizeof(int); - symtab->hash = hash; - hash->link = symtab; - -- ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); -+ ptr = section_ptr_add(st, hash, (2 + nb_buckets + 1) * sizeof(int)); - ptr[0] = nb_buckets; - ptr[1] = 1; - memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); -@@ -953,15 +954,15 @@ - } - - /* put dynamic tag */ --static void put_dt(Section *dynamic, int dt, unsigned long val) -+static void put_dt(TCCState *st, Section *dynamic, int dt, unsigned long val) - { - Elf32_Dyn *dyn; -- dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn)); -+ dyn = section_ptr_add(st, dynamic, sizeof(Elf32_Dyn)); - dyn->d_tag = dt; - dyn->d_un.d_val = val; - } - --static void add_init_array_defines(TCCState *s1, const char *section_name) -+static void add_init_array_defines(TCCState *st, const char *section_name) - { - Section *s; - long end_offset; -@@ -971,7 +972,7 @@ - snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1); - snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1); - -- s = find_section(s1, section_name); -+ s = find_section(st, section_name); - if (!s) { - end_offset = 0; - s = data_section; -@@ -979,22 +980,22 @@ - end_offset = s->data_offset; - } - -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - 0, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, sym_start); -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - end_offset, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, sym_end); - } - - /* add tcc runtime libraries */ --static void tcc_add_runtime(TCCState *s1) -+static void tcc_add_runtime(TCCState *st) - { - char buf[1024]; - --#ifdef CONFIG_TCC_BCHECK -+#if 0 - if (do_bounds_check) { - unsigned long *ptr; - Section *init_section; -@@ -1002,71 +1003,71 @@ - int sym_index; - - /* XXX: add an object file to do that */ -- ptr = section_ptr_add(bounds_section, sizeof(unsigned long)); -+ ptr = section_ptr_add(st, bounds_section, sizeof(unsigned long)); - *ptr = 0; -- add_elf_sym(symtab_section, 0, 0, -+ add_elf_sym(st, symtab_section, 0, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - bounds_section->sh_num, "__bounds_start"); - /* add bound check code */ -- snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o"); -- tcc_add_file(s1, buf); -+ snprintf(buf, sizeof(buf), "%s/%s", Tcl_GetString(tcc_lib_path), "bcheck.o"); -+ tcc_add_file(st, buf); - #ifdef TCC_TARGET_I386 -- if (s1->output_type != TCC_OUTPUT_MEMORY) { -+ if (st->output_type != TCC_OUTPUT_MEMORY) { - /* add 'call __bound_init()' in .init section */ -- init_section = find_section(s1, ".init"); -- pinit = section_ptr_add(init_section, 5); -+ init_section = find_section(st, ".init"); -+ pinit = section_ptr_add(st, init_section, 5); - pinit[0] = 0xe8; - put32(pinit + 1, -4); - sym_index = find_elf_sym(symtab_section, "__bound_init"); -- put_elf_reloc(symtab_section, init_section, -+ put_elf_reloc(st, symtab_section, init_section, - init_section->data_offset - 4, R_386_PC32, sym_index); - } - #endif - } - #endif - /* add libc */ -- if (!s1->nostdlib) { -- tcc_add_library(s1, "c"); -+ if (!st->nostdlib) { -+ tcc_add_library(st, "c"); - -- snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a"); -- tcc_add_file(s1, buf); -+ snprintf(buf, sizeof(buf), "%s/lib/%s", Tcl_GetString(st->tcc_lib_path), "libtcc1.a"); -+ tcc_add_file(st, buf); - } - /* add crt end if not memory output */ -- if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) { -- tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); -+ if (st->output_type != TCC_OUTPUT_MEMORY && !st->nostdlib) { -+ tcc_add_file(st, CONFIG_TCC_CRT_PREFIX "/crtn.o"); - } - } - - /* add various standard linker symbols (must be done after the - sections are filled (for example after allocating common - symbols)) */ --static void tcc_add_linker_symbols(TCCState *s1) -+static void tcc_add_linker_symbols(TCCState *st) - { - char buf[1024]; - int i; - Section *s; - -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - text_section->data_offset, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "_etext"); -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - data_section->data_offset, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - data_section->sh_num, "_edata"); -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - bss_section->data_offset, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - bss_section->sh_num, "_end"); - /* horrible new standard ldscript defines */ -- add_init_array_defines(s1, ".preinit_array"); -- add_init_array_defines(s1, ".init_array"); -- add_init_array_defines(s1, ".fini_array"); -+ add_init_array_defines(st, ".preinit_array"); -+ add_init_array_defines(st, ".init_array"); -+ add_init_array_defines(st, ".fini_array"); - - /* add start and stop symbols for sections whose name can be - expressed in C */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - if (s->sh_type == SHT_PROGBITS && - (s->sh_flags & SHF_ALLOC)) { - const char *p; -@@ -1078,17 +1079,17 @@ - ch = *p; - if (!ch) - break; -- if (!isid(ch) && !isnum(ch)) -+ if (!isid(st, ch) && !isnum(st, ch)) - goto next_sec; - p++; - } - snprintf(buf, sizeof(buf), "__start_%s", s->name); -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - 0, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, buf); - snprintf(buf, sizeof(buf), "__stop_%s", s->name); -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - s->data_offset, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, buf); -@@ -1108,15 +1109,15 @@ - #endif - #endif - --static void tcc_output_binary(TCCState *s1, FILE *f, -+static void tcc_output_binary(TCCState *st, FILE *f, - const int *section_order) - { - Section *s; - int i, offset, size; - - offset = 0; -- for(i=1;inb_sections;i++) { -- s = s1->sections[section_order[i]]; -+ for(i=1;inb_sections;i++) { -+ s = st->sections[section_order[i]]; - if (s->sh_type != SHT_NOBITS && - (s->sh_flags & SHF_ALLOC)) { - while (offset < s->sh_offset) { -@@ -1132,7 +1133,7 @@ - - /* output an ELF file */ - /* XXX: suppress unneeded sections */ --int tcc_output_file(TCCState *s1, const char *filename) -+int tcc_output_file(TCCState *st, const char *filename) - { - Elf32_Ehdr ehdr; - FILE *f; -@@ -1149,11 +1150,11 @@ - int type, file_type; - unsigned long rel_addr, rel_size; - -- file_type = s1->output_type; -- s1->nb_errors = 0; -+ file_type = st->output_type; -+ st->nb_errors = 0; - - if (file_type != TCC_OUTPUT_OBJ) { -- tcc_add_runtime(s1); -+ tcc_add_runtime(st); - } - - phdr = NULL; -@@ -1166,9 +1167,9 @@ - if (file_type != TCC_OUTPUT_OBJ) { - relocate_common_syms(); - -- tcc_add_linker_symbols(s1); -+ tcc_add_linker_symbols(st); - -- if (!s1->static_link) { -+ if (!st->static_link) { - const char *name; - int sym_index, index; - Elf32_Sym *esym, *sym_end; -@@ -1176,30 +1177,30 @@ - if (file_type == TCC_OUTPUT_EXE) { - char *ptr; - /* add interpreter section only if executable */ -- interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); -+ interp = new_section(st, ".interp", SHT_PROGBITS, SHF_ALLOC); - interp->sh_addralign = 1; -- ptr = section_ptr_add(interp, sizeof(elf_interp)); -+ ptr = section_ptr_add(st, interp, sizeof(elf_interp)); - strcpy(ptr, elf_interp); - } - - /* add dynamic symbol table */ -- s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, -+ st->dynsym = new_symtab(st, ".dynsym", SHT_DYNSYM, SHF_ALLOC, - ".dynstr", - ".hash", SHF_ALLOC); -- dynstr = s1->dynsym->link; -+ dynstr = st->dynsym->link; - - /* add dynamic section */ -- dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, -+ dynamic = new_section(st, ".dynamic", SHT_DYNAMIC, - SHF_ALLOC | SHF_WRITE); - dynamic->link = dynstr; - dynamic->sh_entsize = sizeof(Elf32_Dyn); - - /* add PLT */ -- s1->plt = new_section(s1, ".plt", SHT_PROGBITS, -+ st->plt = new_section(st, ".plt", SHT_PROGBITS, - SHF_ALLOC | SHF_EXECINSTR); -- s1->plt->sh_entsize = 4; -+ st->plt->sh_entsize = 4; - -- build_got(s1); -+ build_got(st); - - /* scan for undefined symbols and see if they are in the - dynamic symbols. If a symbol STT_FUNC is found, then we -@@ -1213,12 +1214,12 @@ - sym++) { - if (sym->st_shndx == SHN_UNDEF) { - name = symtab_section->link->data + sym->st_name; -- sym_index = find_elf_sym(s1->dynsymtab_section, name); -+ sym_index = find_elf_sym(st->dynsymtab_section, name); - if (sym_index) { -- esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index]; -+ esym = &((Elf32_Sym *)st->dynsymtab_section->data)[sym_index]; - type = ELF32_ST_TYPE(esym->st_info); - if (type == STT_FUNC) { -- put_got_entry(s1, R_JMP_SLOT, esym->st_size, -+ put_got_entry(st, R_JMP_SLOT, esym->st_size, - esym->st_info, - sym - (Elf32_Sym *)symtab_section->data); - } else if (type == STT_OBJECT) { -@@ -1226,10 +1227,10 @@ - offset = bss_section->data_offset; - /* XXX: which alignment ? */ - offset = (offset + 16 - 1) & -16; -- index = put_elf_sym(s1->dynsym, offset, esym->st_size, -+ index = put_elf_sym(st, st->dynsym, offset, esym->st_size, - esym->st_info, 0, - bss_section->sh_num, name); -- put_elf_reloc(s1->dynsym, bss_section, -+ put_elf_reloc(st, st->dynsym, bss_section, - offset, R_COPY, index); - offset += esym->st_size; - bss_section->data_offset = offset; -@@ -1241,45 +1242,45 @@ - if (ELF32_ST_BIND(sym->st_info) == STB_WEAK || - !strcmp(name, "_fp_hw")) { - } else { -- error_noabort("undefined symbol '%s'", name); -+ error_noabort(st, "undefined symbol '%s'", name); - } - } -- } else if (s1->rdynamic && -+ } else if (st->rdynamic && - ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { - /* if -rdynamic option, then export all non - local symbols */ - name = symtab_section->link->data + sym->st_name; -- put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, -+ put_elf_sym(st, st->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - } - } - -- if (s1->nb_errors) -+ if (st->nb_errors) - goto fail; - - /* now look at unresolved dynamic symbols and export - corresponding symbol */ -- sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data + -- s1->dynsymtab_section->data_offset); -- for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1; -+ sym_end = (Elf32_Sym *)(st->dynsymtab_section->data + -+ st->dynsymtab_section->data_offset); -+ for(esym = (Elf32_Sym *)st->dynsymtab_section->data + 1; - esym < sym_end; - esym++) { - if (esym->st_shndx == SHN_UNDEF) { -- name = s1->dynsymtab_section->link->data + esym->st_name; -+ name = st->dynsymtab_section->link->data + esym->st_name; - sym_index = find_elf_sym(symtab_section, name); - if (sym_index) { - /* XXX: avoid adding a symbol if already - present because of -rdynamic ? */ - sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; -- put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, -+ put_elf_sym(st, st->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - } else { - if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) { - /* weak symbols can stay undefined */ - } else { -- warning("undefined dynamic symbol '%s'", name); -+ warning(st, "undefined dynamic symbol '%s'", name); - } - } - } -@@ -1288,58 +1289,55 @@ - int nb_syms; - /* shared library case : we simply export all the global symbols */ - nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym); -- s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); -+ st->symtab_to_dynsym = tcc_mallocz(st, sizeof(int) * nb_syms); - for(sym = (Elf32_Sym *)symtab_section->data + 1; - sym < sym_end; - sym++) { - if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { - name = symtab_section->link->data + sym->st_name; -- index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, -+ index = put_elf_sym(st, st->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); -- s1->symtab_to_dynsym[sym - -+ st->symtab_to_dynsym[sym - - (Elf32_Sym *)symtab_section->data] = - index; - } - } - } - -- build_got_entries(s1); -+ build_got_entries(st); - - /* add a list of needed dlls */ -- for(i = 0; i < s1->nb_loaded_dlls; i++) { -- DLLReference *dllref = s1->loaded_dlls[i]; -+ for(i = 0; i < st->nb_loaded_dlls; i++) { -+ DLLReference *dllref = st->loaded_dlls[i]; - if (dllref->level == 0) -- put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); -+ put_dt(st, dynamic, DT_NEEDED, put_elf_str(st, dynstr, dllref->name)); - } - /* XXX: currently, since we do not handle PIC code, we - must relocate the readonly segments */ -- if (file_type == TCC_OUTPUT_DLL) { -- if (s1->soname) -- put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); -- put_dt(dynamic, DT_TEXTREL, 0); -- } -+ if (file_type == TCC_OUTPUT_DLL) -+ put_dt(st, dynamic, DT_TEXTREL, 0); - - /* add necessary space for other entries */ - saved_dynamic_data_offset = dynamic->data_offset; - dynamic->data_offset += 8 * 9; - } else { - /* still need to build got entries in case of static link */ -- build_got_entries(s1); -+ build_got_entries(st); - } - } - - memset(&ehdr, 0, sizeof(ehdr)); - - /* we add a section for symbols */ -- strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); -- put_elf_str(strsec, ""); -+ strsec = new_section(st, ".shstrtab", SHT_STRTAB, 0); -+ put_elf_str(st, strsec, ""); - - /* compute number of sections */ -- shnum = s1->nb_sections; -+ shnum = st->nb_sections; - - /* this array is used to reorder sections in the output file */ -- section_order = tcc_malloc(sizeof(int) * shnum); -+ section_order = tcc_malloc(st, sizeof(int) * shnum); - section_order[0] = 0; - sh_order_index = 1; - -@@ -1350,7 +1348,7 @@ - phnum = 0; - break; - case TCC_OUTPUT_EXE: -- if (!s1->static_link) -+ if (!st->static_link) - phnum = 4; - else - phnum = 2; -@@ -1364,37 +1362,37 @@ - section should be output */ - /* NOTE: the strsec section comes last, so its size is also - correct ! */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -- s->sh_name = put_elf_str(strsec, s->name); -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; -+ s->sh_name = put_elf_str(st, strsec, s->name); - /* when generating a DLL, we include relocations but we may - patch them */ - if (file_type == TCC_OUTPUT_DLL && - s->sh_type == SHT_REL && - !(s->sh_flags & SHF_ALLOC)) { -- prepare_dynamic_rel(s1, s); -+ prepare_dynamic_rel(st, s); - } else if (do_debug || - file_type == TCC_OUTPUT_OBJ || - (s->sh_flags & SHF_ALLOC) || -- i == (s1->nb_sections - 1)) { -+ i == (st->nb_sections - 1)) { - /* we output all sections if debug or object file */ - s->sh_size = s->data_offset; - } - } - - /* allocate program segment headers */ -- phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr)); -+ phdr = tcc_mallocz(st, phnum * sizeof(Elf32_Phdr)); - -- if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { -+ if (st->output_format == TCC_OUTPUT_FORMAT_ELF) { - file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr); - } else { - file_offset = 0; - } - if (phnum > 0) { - /* compute section to program header mapping */ -- if (s1->has_text_addr) { -+ if (st->has_text_addr) { - int a_offset, p_offset; -- addr = s1->text_addr; -+ addr = st->text_addr; - /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % - ELF_PAGE_SIZE */ - a_offset = addr & (ELF_PAGE_SIZE - 1); -@@ -1432,8 +1430,8 @@ - relocations, progbits, nobits */ - /* XXX: do faster and simpler sorting */ - for(k = 0; k < 5; k++) { -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - /* compute if section should be included */ - if (j == 0) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != -@@ -1493,7 +1491,7 @@ - ph->p_memsz = addr - ph->p_vaddr; - ph++; - if (j == 0) { -- if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { -+ if (st->output_format == TCC_OUTPUT_FORMAT_ELF) { - /* if in the middle of a page, we duplicate the page in - memory so that one copy is RX and the other is RW */ - if ((addr & (ELF_PAGE_SIZE - 1)) != 0) -@@ -1536,29 +1534,29 @@ - ph->p_align = dynamic->sh_addralign; - - /* put GOT dynamic section address */ -- put32(s1->got->data, dynamic->sh_addr); -+ put32(st->got->data, dynamic->sh_addr); - - /* relocate the PLT */ - if (file_type == TCC_OUTPUT_EXE) { - uint8_t *p, *p_end; - -- p = s1->plt->data; -- p_end = p + s1->plt->data_offset; -+ p = st->plt->data; -+ p_end = p + st->plt->data_offset; - if (p < p_end) { - #if defined(TCC_TARGET_I386) -- put32(p + 2, get32(p + 2) + s1->got->sh_addr); -- put32(p + 8, get32(p + 8) + s1->got->sh_addr); -+ put32(p + 2, get32(p + 2) + st->got->sh_addr); -+ put32(p + 8, get32(p + 8) + st->got->sh_addr); - p += 16; - while (p < p_end) { -- put32(p + 2, get32(p + 2) + s1->got->sh_addr); -+ put32(p + 2, get32(p + 2) + st->got->sh_addr); - p += 16; - } - #elif defined(TCC_TARGET_ARM) - int x; -- x=s1->got->sh_addr - s1->plt->sh_addr - 12; -+ x=st->got->sh_addr - st->plt->sh_addr - 12; - p +=16; - while (p < p_end) { -- put32(p + 12, x + get32(p + 12) + s1->plt->data - p); -+ put32(p + 12, x + get32(p + 12) + st->plt->data - p); - p += 16; - } - #elif defined(TCC_TARGET_C67) -@@ -1570,32 +1568,32 @@ - } - - /* relocate symbols in .dynsym */ -- sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset); -- for(sym = (Elf32_Sym *)s1->dynsym->data + 1; -+ sym_end = (Elf32_Sym *)(st->dynsym->data + st->dynsym->data_offset); -+ for(sym = (Elf32_Sym *)st->dynsym->data + 1; - sym < sym_end; - sym++) { - if (sym->st_shndx == SHN_UNDEF) { - /* relocate to the PLT if the symbol corresponds - to a PLT entry */ - if (sym->st_value) -- sym->st_value += s1->plt->sh_addr; -+ sym->st_value += st->plt->sh_addr; - } else if (sym->st_shndx < SHN_LORESERVE) { - /* do symbol relocation */ -- sym->st_value += s1->sections[sym->st_shndx]->sh_addr; -+ sym->st_value += st->sections[sym->st_shndx]->sh_addr; - } - } - - /* put dynamic section entries */ - dynamic->data_offset = saved_dynamic_data_offset; -- put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); -- put_dt(dynamic, DT_STRTAB, dynstr->sh_addr); -- put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); -- put_dt(dynamic, DT_STRSZ, dynstr->data_offset); -- put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym)); -- put_dt(dynamic, DT_REL, rel_addr); -- put_dt(dynamic, DT_RELSZ, rel_size); -- put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel)); -- put_dt(dynamic, DT_NULL, 0); -+ put_dt(st, dynamic, DT_HASH, st->dynsym->hash->sh_addr); -+ put_dt(st, dynamic, DT_STRTAB, dynstr->sh_addr); -+ put_dt(st, dynamic, DT_SYMTAB, st->dynsym->sh_addr); -+ put_dt(st, dynamic, DT_STRSZ, dynstr->data_offset); -+ put_dt(st, dynamic, DT_SYMENT, sizeof(Elf32_Sym)); -+ put_dt(st, dynamic, DT_REL, rel_addr); -+ put_dt(st, dynamic, DT_RELSZ, rel_size); -+ put_dt(st, dynamic, DT_RELENT, sizeof(Elf32_Rel)); -+ put_dt(st, dynamic, DT_NULL, 0); - } - - ehdr.e_phentsize = sizeof(Elf32_Phdr); -@@ -1604,8 +1602,8 @@ - } - - /* all other sections come after */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) - continue; - section_order[sh_order_index++] = i; -@@ -1620,9 +1618,9 @@ - /* if building executable or DLL, then relocate each section - except the GOT which is already relocated */ - if (file_type != TCC_OUTPUT_OBJ) { -- relocate_syms(s1, 0); -+ relocate_syms(st, 0); - -- if (s1->nb_errors != 0) { -+ if (st->nb_errors != 0) { - fail: - ret = -1; - goto the_end; -@@ -1630,25 +1628,25 @@ - - /* relocate sections */ - /* XXX: ignore sections with allocated relocations ? */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -- if (s->reloc && s != s1->got) -- relocate_section(s1, s); -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; -+ if (s->reloc && s != st->got) -+ relocate_section(st, s); - } - - /* relocate relocation entries if the relocation tables are - allocated in the executable */ -- for(i = 1; i < s1->nb_sections; i++) { -- s = s1->sections[i]; -+ for(i = 1; i < st->nb_sections; i++) { -+ s = st->sections[i]; - if ((s->sh_flags & SHF_ALLOC) && - s->sh_type == SHT_REL) { -- relocate_rel(s1, s); -+ relocate_rel(st, s); - } - } - - /* get entry point address */ - if (file_type == TCC_OUTPUT_EXE) -- ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start"); -+ ehdr.e_entry = (unsigned long)tcc_get_symbol_err(st, "_start"); - else - ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ - } -@@ -1660,20 +1658,18 @@ - mode = 0777; - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); - if (fd < 0) { -- error_noabort("could not write '%s'", filename); -+ error_noabort(st, "could not write '%s'", filename); - goto fail; - } - f = fdopen(fd, "wb"); -- if (verbose) -- printf("<- %s\n", filename); - - #ifdef TCC_TARGET_COFF -- if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) { -- tcc_output_coff(s1, f); -+ if (st->output_format == TCC_OUTPUT_FORMAT_COFF) { -+ tcc_output_coff(st, f); - } else - #endif -- if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { -- sort_syms(s1, symtab_section); -+ if (st->output_format == TCC_OUTPUT_FORMAT_ELF) { -+ sort_syms(st, symtab_section); - - /* align to 4 */ - file_offset = (file_offset + 3) & -4; -@@ -1721,8 +1717,8 @@ - fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f); - offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr); - -- for(i=1;inb_sections;i++) { -- s = s1->sections[section_order[i]]; -+ for(i=1;inb_sections;i++) { -+ s = st->sections[section_order[i]]; - if (s->sh_type != SHT_NOBITS) { - while (offset < s->sh_offset) { - fputc(0, f); -@@ -1740,10 +1736,10 @@ - offset++; - } - -- for(i=0;inb_sections;i++) { -+ for(i=0;inb_sections;i++) { - sh = &shdr; - memset(sh, 0, sizeof(Elf32_Shdr)); -- s = s1->sections[i]; -+ s = st->sections[i]; - if (s) { - sh->sh_name = s->sh_name; - sh->sh_type = s->sh_type; -@@ -1760,26 +1756,26 @@ - fwrite(sh, 1, sizeof(Elf32_Shdr), f); - } - } else { -- tcc_output_binary(s1, f, section_order); -+ tcc_output_binary(st, f, section_order); - } - fclose(f); - - ret = 0; - the_end: -- tcc_free(s1->symtab_to_dynsym); -- tcc_free(section_order); -- tcc_free(phdr); -- tcc_free(s1->got_offsets); -+ ckfree((char *)st->symtab_to_dynsym); -+ ckfree((char *)section_order); -+ ckfree((char *)phdr); -+ ckfree((char *)st->got_offsets); - return ret; - } - --static void *load_data(int fd, unsigned long file_offset, unsigned long size) -+static void *load_data(TCCState *st, Tcl_Channel fd, unsigned long file_offset, unsigned long size) - { - void *data; - -- data = tcc_malloc(size); -- lseek(fd, file_offset, SEEK_SET); -- read(fd, data, size); -+ data = tcc_malloc(st, size); -+ Tcl_Seek(fd, file_offset, SEEK_SET); -+ Tcl_Read(fd, data, size); - return data; - } - -@@ -1792,8 +1788,8 @@ - - /* load an object file and merge it with current files */ - /* XXX: handle correctly stab (debug) info */ --static int tcc_load_object_file(TCCState *s1, -- int fd, unsigned long file_offset) -+static int tcc_load_object_file(TCCState *st, -+ Tcl_Channel fd, unsigned long file_offset) - { - Elf32_Ehdr ehdr; - Elf32_Shdr *shdr, *sh; -@@ -1806,7 +1802,7 @@ - Elf32_Rel *rel, *rel_end; - Section *s; - -- if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) -+ if (Tcl_Read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr)) - goto fail1; - if (ehdr.e_ident[0] != ELFMAG0 || - ehdr.e_ident[1] != ELFMAG1 || -@@ -1820,17 +1816,17 @@ - if (ehdr.e_ident[5] != ELFDATA2LSB || - ehdr.e_machine != EM_TCC_TARGET) { - fail1: -- error_noabort("invalid object file"); -+ error_noabort(st, "invalid object file"); - return -1; - } - /* read sections */ -- shdr = load_data(fd, file_offset + ehdr.e_shoff, -+ shdr = load_data(st, fd, file_offset + ehdr.e_shoff, - sizeof(Elf32_Shdr) * ehdr.e_shnum); -- sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum); -+ sm_table = tcc_mallocz(st, sizeof(SectionMergeInfo) * ehdr.e_shnum); - - /* load section names */ - sh = &shdr[ehdr.e_shstrndx]; -- strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); -+ strsec = load_data(st, fd, file_offset + sh->sh_offset, sh->sh_size); - - /* load symtab and strtab */ - old_to_new_syms = NULL; -@@ -1841,18 +1837,18 @@ - sh = &shdr[i]; - if (sh->sh_type == SHT_SYMTAB) { - if (symtab) { -- error_noabort("object must contain only one symtab"); -+ error_noabort(st, "object must contain only one symtab"); - fail: - ret = -1; - goto the_end; - } - nb_syms = sh->sh_size / sizeof(Elf32_Sym); -- symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); -+ symtab = load_data(st, fd, file_offset + sh->sh_offset, sh->sh_size); - sm_table[i].s = symtab_section; - - /* now load strtab */ - sh = &shdr[sh->sh_link]; -- strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); -+ strtab = load_data(st, fd, file_offset + sh->sh_offset, sh->sh_size); - } - } - -@@ -1875,8 +1871,8 @@ - if (sh->sh_addralign < 1) - sh->sh_addralign = 1; - /* find corresponding section, if any */ -- for(j = 1; j < s1->nb_sections;j++) { -- s = s1->sections[j]; -+ for(j = 1; j < st->nb_sections;j++) { -+ s = st->sections[j]; - if (!strcmp(s->name, sh_name)) { - if (!strncmp(sh_name, ".gnu.linkonce", - sizeof(".gnu.linkonce") - 1)) { -@@ -1892,7 +1888,7 @@ - } - } - /* not found: create new section */ -- s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags); -+ s = new_section(st, sh_name, sh->sh_type, sh->sh_flags); - /* take as much info as possible from the section. sh_link and - sh_info will be updated later */ - s->sh_addralign = sh->sh_addralign; -@@ -1900,7 +1896,7 @@ - sm_table[i].new_section = 1; - found: - if (sh->sh_type != s->sh_type) { -- error_noabort("invalid section type"); -+ error_noabort(st, "invalid section type"); - goto fail; - } - -@@ -1917,9 +1913,9 @@ - size = sh->sh_size; - if (sh->sh_type != SHT_NOBITS) { - unsigned char *ptr; -- lseek(fd, file_offset + sh->sh_offset, SEEK_SET); -- ptr = section_ptr_add(s, size); -- read(fd, ptr, size); -+ Tcl_Seek(fd, file_offset + sh->sh_offset, SEEK_SET); -+ ptr = section_ptr_add(st, s, size); -+ Tcl_Read(fd, ptr, size); - } else { - s->data_offset += size; - } -@@ -1938,13 +1934,13 @@ - if (sh->sh_type == SHT_REL) { - s->sh_info = sm_table[sh->sh_info].s->sh_num; - /* update backward link */ -- s1->sections[s->sh_info]->reloc = s; -+ st->sections[s->sh_info]->reloc = s; - } - } - sm = sm_table; - - /* resolve symbols */ -- old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int)); -+ old_to_new_syms = tcc_mallocz(st, nb_syms * sizeof(int)); - - sym = symtab + 1; - for(i = 1; i < nb_syms; i++, sym++) { -@@ -1973,7 +1969,7 @@ - } - /* add symbol */ - name = strtab + sym->st_name; -- sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, -+ sym_index = add_elf_sym(st, symtab_section, sym->st_value, sym->st_size, - sym->st_info, sym->st_other, - sym->st_shndx, name); - old_to_new_syms[i] = sym_index; -@@ -2006,7 +2002,7 @@ - /* ignore link_once in rel section. */ - if (!sym_index && !sm->link_once) { - invalid_reloc: -- error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", -+ error_noabort(st, "Invalid relocation entry [%2d] '%s' @ %.8x", - i, strsec + sh->sh_name, rel->r_offset); - goto fail; - } -@@ -2022,12 +2018,12 @@ - - ret = 0; - the_end: -- tcc_free(symtab); -- tcc_free(strtab); -- tcc_free(old_to_new_syms); -- tcc_free(sm_table); -- tcc_free(strsec); -- tcc_free(shdr); -+ ckfree((char *)symtab); -+ ckfree((char *)strtab); -+ ckfree((char *)old_to_new_syms); -+ ckfree((char *)sm_table); -+ ckfree((char *)strsec); -+ ckfree((char *)shdr); - return ret; - } - -@@ -2049,7 +2045,7 @@ - } - - /* load only the objects which resolve undefined symbols */ --static int tcc_load_alacarte(TCCState *s1, int fd, int size) -+static int tcc_load_alacarte(TCCState *st, Tcl_Channel fd, int size) - { - int i, bound, nsyms, sym_index, off, ret; - uint8_t *data; -@@ -2057,8 +2053,8 @@ - const uint8_t *ar_index; - Elf32_Sym *sym; - -- data = tcc_malloc(size); -- if (read(fd, data, size) != size) -+ data = tcc_malloc(st, size); -+ if (Tcl_Read(fd, data, size) != size) - goto fail; - nsyms = get_be32(data); - ar_index = data + 4; -@@ -2076,8 +2072,8 @@ - printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx); - #endif - ++bound; -- lseek(fd, off, SEEK_SET); -- if(tcc_load_object_file(s1, fd, off) < 0) { -+ Tcl_Seek(fd, off, SEEK_SET); -+ if(tcc_load_object_file(st, fd, off) < 0) { - fail: - ret = -1; - goto the_end; -@@ -2088,12 +2084,12 @@ - } while(bound); - ret = 0; - the_end: -- tcc_free(data); -+ ckfree((char *)data); - return ret; - } - - /* load a '.a' file */ --static int tcc_load_archive(TCCState *s1, int fd) -+static int tcc_load_archive(TCCState *st, Tcl_Channel fd) - { - ArchiveHeader hdr; - char ar_size[11]; -@@ -2103,14 +2099,14 @@ - unsigned long file_offset; - - /* skip magic which was already checked */ -- read(fd, magic, sizeof(magic)); -+ Tcl_Read(fd, magic, sizeof(magic)); - - for(;;) { -- len = read(fd, &hdr, sizeof(hdr)); -+ len = Tcl_Read(fd, (char *)&hdr, sizeof(hdr)); - if (len == 0) - break; - if (len != sizeof(hdr)) { -- error_noabort("invalid archive"); -+ error_noabort(st, "invalid archive"); - return -1; - } - memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size)); -@@ -2122,24 +2118,24 @@ - break; - } - ar_name[i + 1] = '\0'; -- // printf("name='%s' size=%d %s\n", ar_name, size, ar_size); -- file_offset = lseek(fd, 0, SEEK_CUR); -+ /* printf("name='%s' size=%d %s\n", ar_name, size, ar_size); */ -+ file_offset = Tcl_Seek(fd, 0, SEEK_CUR); - /* align to even */ - size = (size + 1) & ~1; - if (!strcmp(ar_name, "/")) { - /* coff symbol table : we handle it */ -- if(s1->alacarte_link) -- return tcc_load_alacarte(s1, fd, size); -- } else if (!strcmp(ar_name, "//") || -+ if(st->alacarte_link) -+ return tcc_load_alacarte(st, fd, size); -+ } else if (!strcmp(ar_name, "/*") || - !strcmp(ar_name, "__.SYMDEF") || - !strcmp(ar_name, "__.SYMDEF/") || - !strcmp(ar_name, "ARFILENAMES/")) { - /* skip symbol table or archive names */ - } else { -- if (tcc_load_object_file(s1, fd, file_offset) < 0) -+ if (tcc_load_object_file(st, fd, file_offset) < 0) - return -1; - } -- lseek(fd, file_offset + size, SEEK_SET); -+ Tcl_Seek(fd, file_offset + size, SEEK_SET); - } - return 0; - } -@@ -2147,7 +2143,7 @@ - /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL - is referenced by the user (so it should be added as DT_NEEDED in - the generated ELF file) */ --static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) -+static int tcc_load_dll(TCCState *st, Tcl_Channel fd, const char *filename, int level) - { - Elf32_Ehdr ehdr; - Elf32_Shdr *shdr, *sh, *sh1; -@@ -2155,20 +2151,20 @@ - Elf32_Sym *sym, *dynsym; - Elf32_Dyn *dt, *dynamic; - unsigned char *dynstr; -- const char *name, *soname; -+ const char *name, *soname, *p; - DLLReference *dllref; - -- read(fd, &ehdr, sizeof(ehdr)); -+ Tcl_Read(fd, (char *)&ehdr, sizeof(ehdr)); - - /* test CPU specific stuff */ - if (ehdr.e_ident[5] != ELFDATA2LSB || - ehdr.e_machine != EM_TCC_TARGET) { -- error_noabort("bad architecture"); -+ error_noabort(st, "bad architecture"); - return -1; - } - - /* read sections */ -- shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum); -+ shdr = load_data(st, fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum); - - /* load dynamic section and dynamic symbols */ - nb_syms = 0; -@@ -2180,13 +2176,13 @@ - switch(sh->sh_type) { - case SHT_DYNAMIC: - nb_dts = sh->sh_size / sizeof(Elf32_Dyn); -- dynamic = load_data(fd, sh->sh_offset, sh->sh_size); -+ dynamic = load_data(st, fd, sh->sh_offset, sh->sh_size); - break; - case SHT_DYNSYM: - nb_syms = sh->sh_size / sizeof(Elf32_Sym); -- dynsym = load_data(fd, sh->sh_offset, sh->sh_size); -+ dynsym = load_data(st, fd, sh->sh_offset, sh->sh_size); - sh1 = &shdr[sh->sh_link]; -- dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size); -+ dynstr = load_data(st, fd, sh1->sh_offset, sh1->sh_size); - break; - default: - break; -@@ -2194,7 +2190,10 @@ - } - - /* compute the real library name */ -- soname = tcc_basename(filename); -+ soname = filename; -+ p = strrchr(soname, '/'); -+ if (p) -+ soname = p + 1; - - for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { - if (dt->d_tag == DT_SONAME) { -@@ -2203,8 +2202,8 @@ - } - - /* if the dll is already loaded, do not load it */ -- for(i = 0; i < s1->nb_loaded_dlls; i++) { -- dllref = s1->loaded_dlls[i]; -+ for(i = 0; i < st->nb_loaded_dlls; i++) { -+ dllref = st->loaded_dlls[i]; - if (!strcmp(soname, dllref->name)) { - /* but update level if needed */ - if (level < dllref->level) -@@ -2214,13 +2213,13 @@ - } - } - -- // printf("loading dll '%s'\n", soname); -+ /* printf("loading dll '%s'\n", soname); */ - - /* add the dll and its level */ -- dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname)); -+ dllref = tcc_malloc(st, sizeof(DLLReference) + strlen(soname)); - dllref->level = level; - strcpy(dllref->name, soname); -- dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); -+ dynarray_add(st, (void ***)&st->loaded_dlls, &st->nb_loaded_dlls, dllref); - - /* add dynamic symbols in dynsym_section */ - for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) { -@@ -2228,7 +2227,7 @@ - if (sym_bind == STB_LOCAL) - continue; - name = dynstr + sym->st_name; -- add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, -+ add_elf_sym(st, st->dynsymtab_section, sym->st_value, sym->st_size, - sym->st_info, sym->st_other, sym->st_shndx, name); - } - -@@ -2237,13 +2236,13 @@ - switch(dt->d_tag) { - case DT_NEEDED: - name = dynstr + dt->d_un.d_val; -- for(j = 0; j < s1->nb_loaded_dlls; j++) { -- dllref = s1->loaded_dlls[j]; -+ for(j = 0; j < st->nb_loaded_dlls; j++) { -+ dllref = st->loaded_dlls[j]; - if (!strcmp(name, dllref->name)) - goto already_loaded; - } -- if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { -- error_noabort("referenced dll '%s' not found", name); -+ if (tcc_add_dll(st, name, AFF_REFERENCED_DLL) < 0) { -+ error_noabort(st, "referenced dll '%s' not found", name); - ret = -1; - goto the_end; - } -@@ -2253,10 +2252,10 @@ - } - ret = 0; - the_end: -- tcc_free(dynstr); -- tcc_free(dynsym); -- tcc_free(dynamic); -- tcc_free(shdr); -+ ckfree((char *)dynstr); -+ ckfree((char *)dynsym); -+ ckfree((char *)dynamic); -+ ckfree((char *)shdr); - return ret; - } - -@@ -2264,26 +2263,26 @@ - #define LD_TOK_EOF (-1) - - /* return next ld script token */ --static int ld_next(TCCState *s1, char *name, int name_size) -+static int ld_next(TCCState *st, char *name, int name_size) - { - int c; - char *q; - - redo: -- switch(ch) { -+ switch(fch) { - case ' ': - case '\t': - case '\f': - case '\v': - case '\r': - case '\n': -- inp(); -+ inp(st); - goto redo; - case '/': -- minp(); -- if (ch == '*') { -- file->buf_ptr = parse_comment(file->buf_ptr); -- ch = file->buf_ptr[0]; -+ minp(st); -+ if (fch == '*') { -+ file->buf_ptr = parse_comment(st, file->buf_ptr); -+ fch = file->buf_ptr[0]; - goto redo; - } else { - q = name; -@@ -2291,60 +2290,8 @@ - goto parse_name; - } - break; -- /* case 'a' ... 'z': */ -- case 'a': -- case 'b': -- case 'c': -- case 'd': -- case 'e': -- case 'f': -- case 'g': -- case 'h': -- case 'i': -- case 'j': -- case 'k': -- case 'l': -- case 'm': -- case 'n': -- case 'o': -- case 'p': -- case 'q': -- case 'r': -- case 's': -- case 't': -- case 'u': -- case 'v': -- case 'w': -- case 'x': -- case 'y': -- case 'z': -- /* case 'A' ... 'z': */ -- case 'A': -- case 'B': -- case 'C': -- case 'D': -- case 'E': -- case 'F': -- case 'G': -- case 'H': -- case 'I': -- case 'J': -- case 'K': -- case 'L': -- case 'M': -- case 'N': -- case 'O': -- case 'P': -- case 'Q': -- case 'R': -- case 'S': -- case 'T': -- case 'U': -- case 'V': -- case 'W': -- case 'X': -- case 'Y': -- case 'Z': -+ case 'a' ... 'z': -+ case 'A' ... 'Z': - case '_': - case '\\': - case '.': -@@ -2353,15 +2300,15 @@ - q = name; - parse_name: - for(;;) { -- if (!((ch >= 'a' && ch <= 'z') || -- (ch >= 'A' && ch <= 'Z') || -- (ch >= '0' && ch <= '9') || -- strchr("/.-_+=$:\\,~", ch))) -+ if (!((fch >= 'a' && fch <= 'z') || -+ (fch >= 'A' && fch <= 'Z') || -+ (fch >= '0' && fch <= '9') || -+ strchr("/.-_+=$:\\,~", fch))) - break; - if ((q - name) < name_size - 1) { -- *q++ = ch; -+ *q++ = fch; - } -- minp(); -+ minp(st); - } - *q = '\0'; - c = LD_TOK_NAME; -@@ -2370,8 +2317,8 @@ - c = LD_TOK_EOF; - break; - default: -- c = ch; -- inp(); -+ c = fch; -+ inp(st); - break; - } - #if 0 -@@ -2382,37 +2329,37 @@ - return c; - } - --static int ld_add_file_list(TCCState *s1, int as_needed) -+static int ld_add_file_list(TCCState *st, int as_needed) - { - char filename[1024]; - int t, ret; - -- t = ld_next(s1, filename, sizeof(filename)); -+ t = ld_next(st, filename, sizeof(filename)); - if (t != '(') -- expect("("); -- t = ld_next(s1, filename, sizeof(filename)); -+ expect(st, "("); -+ t = ld_next(st, filename, sizeof(filename)); - for(;;) { - if (t == LD_TOK_EOF) { -- error_noabort("unexpected end of file"); -+ error_noabort(st, "unexpected end of file"); - return -1; - } else if (t == ')') { - break; - } else if (t != LD_TOK_NAME) { -- error_noabort("filename expected"); -+ error_noabort(st, "filename expected"); - return -1; - } - if (!strcmp(filename, "AS_NEEDED")) { -- ret = ld_add_file_list(s1, 1); -+ ret = ld_add_file_list(st, 1); - if (ret) - return ret; - } else { - /* TODO: Implement AS_NEEDED support. Ignore it for now */ - if (!as_needed) -- tcc_add_file(s1, filename); -+ tcc_add_file(st, filename); - } -- t = ld_next(s1, filename, sizeof(filename)); -+ t = ld_next(st, filename, sizeof(filename)); - if (t == ',') { -- t = ld_next(s1, filename, sizeof(filename)); -+ t = ld_next(st, filename, sizeof(filename)); - } - } - return 0; -@@ -2420,35 +2367,35 @@ - - /* interpret a subset of GNU ldscripts to handle the dummy libc.so - files */ --static int tcc_load_ldscript(TCCState *s1) -+static int tcc_load_ldscript(TCCState *st) - { - char cmd[64]; - char filename[1024]; - int t, ret; - -- ch = file->buf_ptr[0]; -- ch = handle_eob(); -+ /*fch = file->buf_ptr[0]; */ -+ fch = handle_eob(st); - for(;;) { -- t = ld_next(s1, cmd, sizeof(cmd)); -+ t = ld_next(st, cmd, sizeof(cmd)); - if (t == LD_TOK_EOF) - return 0; - else if (t != LD_TOK_NAME) - return -1; - if (!strcmp(cmd, "INPUT") || - !strcmp(cmd, "GROUP")) { -- ret = ld_add_file_list(s1, 0); -+ ret = ld_add_file_list(st, 0); - if (ret) - return ret; - } else if (!strcmp(cmd, "OUTPUT_FORMAT") || - !strcmp(cmd, "TARGET")) { - /* ignore some commands */ -- t = ld_next(s1, cmd, sizeof(cmd)); -+ t = ld_next(st, cmd, sizeof(cmd)); - if (t != '(') -- expect("("); -+ expect(st, "("); - for(;;) { -- t = ld_next(s1, filename, sizeof(filename)); -+ t = ld_next(st, filename, sizeof(filename)); - if (t == LD_TOK_EOF) { -- error_noabort("unexpected end of file"); -+ error_noabort(st, "unexpected end of file"); - return -1; - } else if (t == ')') { - break; ---- tcc-0.9.23/tccpe.c 2005-06-17 18:09:15.000000000 -0400 -+++ tcltcc-0.4/generic/win32/tccpe.c 2014-05-01 15:36:39.124555968 -0400 -@@ -155,7 +155,7 @@ - typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; --// WORD TypeOffset[1]; -+/* WORD TypeOffset[1]; */ - } IMAGE_BASE_RELOCATION; - - #define IMAGE_SIZEOF_BASE_RELOCATION 8 -@@ -365,13 +365,13 @@ - - /* ------------------------------------------------------------- */ - #define PE_MERGE_DATA --// #define PE_PRINT_SECTIONS -+/* #define PE_PRINT_SECTIONS */ - - #ifndef MAX_PATH - #define MAX_PATH 260 - #endif - --void error_noabort(const char *, ...); -+void error_noabort(TCCState *st, const char *, ...); - - ST char pe_type; - -@@ -397,7 +397,7 @@ - return sym_index; - } - --#ifdef WIN32 -+#if defined(WIN32) && !defined(CONFIG_TCC_STATIC) - ST void **pe_imp; - ST int nb_pe_imp; - -@@ -420,8 +420,8 @@ - if (hm) { - a = GetProcAddress(hm, buffer); - if (a && STT_OBJECT == type) { -- // need to return a pointer to the address for data objects -- dynarray_add(&pe_imp, &nb_pe_imp, a); -+ /* need to return a pointer to the address for data objects */ -+ dynarray_add(s1, &pe_imp, &nb_pe_imp, a); - a = &pe_imp[nb_pe_imp - 1]; - } - } -@@ -445,8 +445,8 @@ - { - int i; - for (i = 0; i < *n; ++i) -- tcc_free((*pp)[i]); -- tcc_free(*pp); -+ ckfree((char *)(*pp)[i]); -+ ckfree((char *)*pp); - *pp = NULL; - *n = 0; - } -@@ -489,16 +489,16 @@ - return (n + (0x1000 - 1)) & ~(0x1000 - 1); - } - --ST void pe_align_section(Section * s, int a) -+ST void pe_align_section(TCCState *st, Section * s, int a) - { - int i = s->data_offset & (a - 1); - if (i) -- section_ptr_add(s, a - i); -+ section_ptr_add(st, s, a - i); - } - - - /*----------------------------------------------------------------------------*/ --ST int pe_write_pe(struct pe_info *pe) -+ST int pe_write_pe(TCCState * st, struct pe_info *pe) - { - int i; - FILE *op; -@@ -508,7 +508,7 @@ - - op = fopen(pe->filename, "wb"); - if (NULL == op) { -- error_noabort("could not create file: %s", pe->filename); -+ error_noabort(st, "could not create file: %s", pe->filename); - return 1; - } - -@@ -625,7 +625,7 @@ - } - - /*----------------------------------------------------------------------------*/ --ST int pe_add_import(struct pe_info *pe, int sym_index, DWORD offset) -+ST int pe_add_import(TCCState *st, struct pe_info *pe, int sym_index, DWORD offset) - { - int i; - int dll_index; -@@ -640,25 +640,25 @@ - p = pe->imp_info[i]; - goto found_dll; - } -- p = tcc_mallocz(sizeof *p); -+ p = tcc_mallocz(st, sizeof *p); - p->dll_index = dll_index; -- dynarray_add((void ***) &pe->imp_info, &pe->imp_count, p); -+ dynarray_add(st, (void ***) &pe->imp_info, &pe->imp_count, p); - - found_dll: - i = dynarray_assoc((void **) p->symbols, p->sym_count, sym_index); - if (-1 != i) - goto found_sym; -- s = tcc_mallocz(sizeof *s); -+ s = tcc_mallocz(st, sizeof *s); - s->sym_index = sym_index; - s->offset = offset; -- dynarray_add((void ***) &p->symbols, &p->sym_count, s); -+ dynarray_add(st, (void ***) &p->symbols, &p->sym_count, s); - - found_sym: - return 1; - } - - /*----------------------------------------------------------------------------*/ --ST void pe_build_imports(struct pe_info *pe) -+ST void pe_build_imports(TCCState *st, struct pe_info *pe) - { - int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i; - DWORD voffset = pe->thunk->sh_addr - pe->imagebase; -@@ -670,13 +670,13 @@ - if (0 == sym_cnt) - return; - -- pe_align_section(pe->thunk, 16); -+ pe_align_section(st, pe->thunk, 16); - - pe->imp_offs = dll_ptr = pe->thunk->data_offset; - pe->imp_size = (ndlls + 1) * sizeof(struct pe_import_header); - pe->iat_offs = dll_ptr + pe->imp_size; - pe->iat_size = (sym_cnt + ndlls) * sizeof(DWORD); -- section_ptr_add(pe->thunk, pe->imp_size + 2 * pe->iat_size); -+ section_ptr_add(st, pe->thunk, pe->imp_size + 2 * pe->iat_size); - - thk_ptr = pe->iat_offs; - ent_ptr = pe->iat_offs + pe->iat_size; -@@ -689,7 +689,7 @@ - /* put the dll name into the import header */ - if (0 == strncmp(name, "lib", 3)) - name += 3; -- v = put_elf_str(pe->thunk, name); -+ v = put_elf_str(st, pe->thunk, name); - - hdr = (struct pe_import_header *) (pe->thunk->data + dll_ptr); - hdr->first_thunk = thk_ptr + voffset; -@@ -717,18 +717,18 @@ - char buffer[100]; - sprintf(buffer, "IAT.%s", name); - sym_index = -- put_elf_sym(symtab_section, thk_ptr, sizeof(DWORD), -+ put_elf_sym(st, symtab_section, thk_ptr, sizeof(DWORD), - ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), - 0, pe->thunk->sh_num, buffer); - -- put_elf_reloc(symtab_section, text_section, offset, R_386_32, /*R_JMP_SLOT, */ -+ put_elf_reloc(st, symtab_section, text_section, offset, R_386_32, /*R_JMP_SLOT, */ - sym_index); - } - v = pe->thunk->data_offset + voffset; -- section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ -- put_elf_str(pe->thunk, name); -+ section_ptr_add(st, pe->thunk, sizeof(WORD)); /* hint, not used */ -+ put_elf_str(st, pe->thunk, name); - } else { -- v = 0; // last entry is zero -+ v = 0; /* last entry is zero */ - } - *(DWORD *) (pe->thunk->data + thk_ptr) = - *(DWORD *) (pe->thunk->data + ent_ptr) = v; -@@ -751,7 +751,7 @@ - return strcmp(ca, cb); - } - --ST void pe_build_exports(struct pe_info *pe) -+ST void pe_build_exports(TCCState *st, struct pe_info *pe) - { - Elf32_Sym *sym; - DWORD func_offset, voffset; -@@ -761,12 +761,12 @@ - voffset = pe->thunk->sh_addr - pe->imagebase; - sym_count = 0, n = 1, sorted = NULL; - -- // for simplicity only functions are exported -+ /* for simplicity only functions are exported */ - for_sym_in_symtab(sym) - { - if ((sym->st_other & 1) - && sym->st_shndx == text_section->sh_num) -- dynarray_add((void***)&sorted, &sym_count, (void*)n); -+ dynarray_add(st, (void***)&sorted, &sym_count, (void*)n); - ++n; - } - -@@ -774,10 +774,10 @@ - return; - - qsort (sorted, sym_count, sizeof sorted[0], sym_cmp); -- pe_align_section(pe->thunk, 16); -+ pe_align_section(st, pe->thunk, 16); - - pe->exp_offs = pe->thunk->data_offset; -- hdr = section_ptr_add(pe->thunk, -+ hdr = section_ptr_add(st, pe->thunk, - sizeof(struct pe_export_header) + - sym_count * (2 * sizeof(DWORD) + sizeof(WORD))); - -@@ -791,7 +791,7 @@ - hdr->AddressOfNames = hdr->AddressOfFunctions + sym_count * sizeof(DWORD); - hdr->AddressOfNameOrdinals = hdr->AddressOfNames + sym_count * sizeof(DWORD); - hdr->Name = pe->thunk->data_offset + voffset; -- put_elf_str(pe->thunk, tcc_basename(pe->filename)); -+ put_elf_str(st, pe->thunk, tcc_basename(pe->filename)); - - for (ord = 0; ord < sym_count; ++ord) - { -@@ -805,15 +805,15 @@ - *pfunc = sym->st_value + pe->s1->sections[sym->st_shndx]->sh_addr - pe->imagebase; - *pname = pe->thunk->data_offset + voffset; - *pord = ord; -- put_elf_str(pe->thunk, name); -+ put_elf_str(st, pe->thunk, name); - /* printf("export: %s\n", name); */ - } - pe->exp_size = pe->thunk->data_offset - pe->exp_offs; -- tcc_free(sorted); -+ ckfree((char *)sorted); - } - - /* ------------------------------------------------------------- */ --ST void pe_build_reloc(struct pe_info *pe, int *section_order, -+ST void pe_build_reloc(TCCState *st, struct pe_info *pe, int *section_order, - int section_count) - { - DWORD offset, block_ptr, addr; -@@ -831,11 +831,11 @@ - continue; - if (count == 0) { /* new block */ - block_ptr = pe->reloc->data_offset; -- section_ptr_add(pe->reloc, sizeof(struct pe_reloc_header)); -+ section_ptr_add(st, pe->reloc, sizeof(struct pe_reloc_header)); - offset = addr & 0xFFFFFFFF << 12; - } - if ((addr -= offset) < (1 << 12)) { /* one block spans 4k addresses */ -- WORD *wp = section_ptr_add(pe->reloc, sizeof(WORD)); -+ WORD *wp = section_ptr_add(st, pe->reloc, sizeof(WORD)); - *wp = addr | IMAGE_REL_BASED_HIGHLOW << 12; - ++count; - continue; -@@ -853,7 +853,7 @@ - if (count) { /* store the last block and ready for a new one */ - struct pe_reloc_header *hdr; - if (count & 1) -- section_ptr_add(pe->reloc, 2), ++count; -+ section_ptr_add(st, pe->reloc, 2), ++count; - hdr = (struct pe_reloc_header *) (pe->reloc->data + block_ptr); - hdr->offset = offset - pe->imagebase; - hdr->size = -@@ -866,7 +866,7 @@ - } - - /* ------------------------------------------------------------- */ --ST int pe_assign_addresses(struct pe_info *pe) -+ST int pe_assign_addresses(TCCState *st, struct pe_info *pe) - { - int i, k, n; - DWORD addr; -@@ -900,10 +900,10 @@ - if (n == sec_data) { - pe->thunk = s; - si_data = si; -- pe_build_imports(pe); -- pe_build_exports(pe); -+ pe_build_imports(st, pe); -+ pe_build_exports(st, pe); - } else if (n == sec_reloc) { -- pe_build_reloc(pe, section_order, k); -+ pe_build_reloc(st, pe, section_order, k); - } - - if (s->data_offset) { -@@ -916,7 +916,7 @@ - si->sh_size = s->data_offset; - ++pe->sec_count; - } -- //printf("Section %08X %04X %s\n", si->sh_addr, si->data_size, s->name); -+ /*printf("Section %08X %04X %s\n", si->sh_addr, si->data_size, s->name); */ - } - section_order[k] = i, ++k; - } -@@ -926,12 +926,12 @@ - } - - /*----------------------------------------------------------------------------*/ --ST int pe_check_symbols(struct pe_info *pe) -+ST int pe_check_symbols(TCCState *st, struct pe_info *pe) - { - Elf32_Sym *sym; - int ret = 0; - -- pe_align_section(text_section, 8); -+ pe_align_section(st, text_section, 8); - - for_sym_in_symtab(sym) { - if (sym->st_shndx == SHN_UNDEF) { -@@ -941,9 +941,9 @@ - if (sym_index) { - if (type == STT_FUNC) { - unsigned long offset = text_section->data_offset; -- if (pe_add_import(pe, sym_index, offset + 2)) { -+ if (pe_add_import(st, pe, sym_index, offset + 2)) { - /* add the 'jmp IAT[x]' instruction */ -- *(WORD *) section_ptr_add(text_section, 8) = -+ *(WORD *) section_ptr_add(st, text_section, 8) = - 0x25FF; - /* patch the symbol */ - sym->st_shndx = text_section->sh_num; -@@ -951,14 +951,14 @@ - continue; - } - } else if (type == STT_OBJECT) { /* data, ptr to that should be */ -- if (pe_add_import(pe, sym_index, -+ if (pe_add_import(st, pe, sym_index, - (sym - - (Elf32_Sym *) symtab_section->data) | - 0x80000000)) - continue; - } - } -- error_noabort("undefined symbol '%s'", symbol); -+ error_noabort(st, "undefined symbol '%s'", symbol); - ret = 1; - } else - if (pe->s1->rdynamic -@@ -1057,7 +1057,7 @@ - } - #endif - --static int pe_test_cmd(const char **pp, const char *cmd) -+static int pe_test_cmd(TCCState *st, const char **pp, const char *cmd) - { - const char *p; - char *q, buf[16]; -@@ -1065,9 +1065,9 @@ - - p = *pp; - q = buf; -- while (*p != '\0' && !is_space(*p)) { -+ while (*p != '\0' && !is_space(st, *p)) { - if ((q - buf) < sizeof(buf) - 1) -- *q++ = toup(*p); -+ *q++ = toup(st, *p); - p++; - } - *q = '\0'; -@@ -1077,12 +1077,19 @@ - } - - /* ------------------------------------------------------------- */ --int pe_load_def_file(TCCState * s1, FILE * fp) -+int pe_load_def_file(TCCState * st, Tcl_Channel fp) - { - DLLReference *dllref; -+ Tcl_Obj * dline; - int f = 0, sym_index; -- char *p, line[120], dllname[40]; -- while (fgets(line, sizeof line, fp)) { -+ char *p, *line, dllname[40]; -+ dline = Tcl_NewObj(); -+ while (1) { -+ Tcl_SetObjLength(dline,0); -+ if (Tcl_GetsObj(fp, dline)==-1) { -+ break; -+ } -+ line = Tcl_GetString(dline); - p = strchr(line, 0); - while (p > line && p[-1] <= ' ') - --p; -@@ -1094,36 +1101,36 @@ - if (*p && ';' != *p) - switch (f) { - case 0: -- if (!pe_test_cmd((const char **)&p, "LIBRARY")) -+ if (!pe_test_cmd(st, (const char **)&p, "LIBRARY")) - return -1; -- while (is_space(*p)) -+ while (is_space(st, *p)) - p++; -- pstrcpy(dllname, sizeof(dllname), p); -+ pstrcpy(st, dllname, sizeof(dllname), p); - ++f; - continue; - - case 1: -- if (!pe_test_cmd((const char **)&p, "EXPORTS")) -+ if (!pe_test_cmd(st, (const char **)&p, "EXPORTS")) - return -1; - ++f; - continue; - - case 2: - dllref = -- tcc_malloc(sizeof(DLLReference) + strlen(dllname)); -+ tcc_malloc(st, sizeof(DLLReference) + strlen(dllname)); - strcpy(dllref->name, dllname); - dllref->level = 0; -- dynarray_add((void ***) &s1->loaded_dlls, -- &s1->nb_loaded_dlls, dllref); -+ dynarray_add(st, (void ***) &st->loaded_dlls, -+ &st->nb_loaded_dlls, dllref); - ++f; - - default: - /* tccpe needs to know from what dll it should import - the sym */ -- sym_index = add_elf_sym(s1->dynsymtab_section, -+ sym_index = add_elf_sym(st, st->dynsymtab_section, - 0, 0, ELF32_ST_INFO(STB_GLOBAL, - STT_FUNC), -- s1->nb_loaded_dlls - 1, -+ st->nb_loaded_dlls - 1, - text_section->sh_num, p); - continue; - } -@@ -1132,7 +1139,7 @@ - } - - /* ------------------------------------------------------------- */ --void pe_guess_outfile(char *objfilename, int output_type) -+void pe_guess_outfile(TCCState *st, char *objfilename, int output_type) - { - char *ext = strrchr(objfilename, '.'); - if (NULL == ext) -@@ -1146,11 +1153,11 @@ - if (output_type == TCC_OUTPUT_OBJ && strcmp(ext, ".o")) - strcpy(ext, ".o"); - else -- error("no outputfile given"); -+ tcc_error(st, "no outputfile given"); - } - - /* ------------------------------------------------------------- */ --unsigned long pe_add_runtime(TCCState * s1) -+unsigned long pe_add_runtime(TCCState * st) - { - const char *start_symbol; - unsigned long addr; -@@ -1158,42 +1165,42 @@ - if (find_elf_sym(symtab_section, "WinMain")) - pe_type = PE_GUI; - else -- if (TCC_OUTPUT_DLL == s1->output_type) -+ if (TCC_OUTPUT_DLL == st->output_type) - { - pe_type = PE_DLL; -- // need this for 'tccelf.c:relocate_section()' -- s1->output_type = TCC_OUTPUT_EXE; -+ /* need this for 'tccelf.c:relocate_section()' */ -+ st->output_type = TCC_OUTPUT_EXE; - } - - start_symbol = -- TCC_OUTPUT_MEMORY == s1->output_type -+ TCC_OUTPUT_MEMORY == st->output_type - ? PE_GUI == pe_type ? "_runwinmain" : NULL - : PE_DLL == pe_type ? "_dllstart" - : PE_GUI == pe_type ? "_winstart" : "_start"; - - /* grab the startup code from libtcc1 */ - if (start_symbol) -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - 0, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - SHN_UNDEF, start_symbol); - -- if (0 == s1->nostdlib) { -- tcc_add_library(s1, "tcc1"); -- tcc_add_library(s1, "msvcrt"); -+ if (0 == st->nostdlib) { -+ tcc_add_library(st, "tcc1"); -+ tcc_add_library(st, "msvcrt"); - if (PE_DLL == pe_type || PE_GUI == pe_type) { -- tcc_add_library(s1, "kernel32"); -- tcc_add_library(s1, "user32"); -- tcc_add_library(s1, "gdi32"); -+ tcc_add_library(st, "kernel32"); -+ tcc_add_library(st, "user32"); -+ tcc_add_library(st, "gdi32"); - } - } - - addr = start_symbol ? -- (unsigned long) tcc_get_symbol_err(s1, start_symbol) : 0; -+ (unsigned long) tcc_get_symbol_err(st, start_symbol) : 0; - -- if (s1->output_type == TCC_OUTPUT_MEMORY && addr) { -+ if (st->output_type == TCC_OUTPUT_MEMORY && addr) { - /* for -run GUI's, put '_runwinmain' instead of 'main' */ -- add_elf_sym(symtab_section, -+ add_elf_sym(st, symtab_section, - addr, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "main"); -@@ -1214,16 +1221,16 @@ - pe.start_addr = pe_add_runtime(s1); - - relocate_common_syms(); /* assign bss adresses */ -- ret = pe_check_symbols(&pe); -+ ret = pe_check_symbols(s1, &pe); - if (0 == ret) { -- pe_assign_addresses(&pe); -+ pe_assign_addresses(s1, &pe); - relocate_syms(s1, 0); - for (i = 1; i < s1->nb_sections; ++i) { - Section *s = s1->sections[i]; - if (s->reloc) - relocate_section(s1, s); - } -- ret = pe_write_pe(&pe); -+ ret = pe_write_pe(s1, &pe); - } - #ifdef PE_PRINT_SECTIONS - { ---- tcc-0.9.24/tcctok.h 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/generic/tcctok.h 2007-11-07 10:04:32.000000000 -0500 -@@ -130,6 +130,7 @@ - DEF(TOK_memcpy, "memcpy") - DEF(TOK_memset, "memset") - #endif -+ DEF(TOK_alloca, "_alloca_tcc") - DEF(TOK___divdi3, "__divdi3") - DEF(TOK___moddi3, "__moddi3") - DEF(TOK___udivdi3, "__udivdi3") -@@ -208,15 +209,14 @@ - DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") - DEF(TOK___bound_local_new, "__bound_local_new") - DEF(TOK___bound_local_delete, "__bound_local_delete") -- DEF(TOK_malloc, "malloc") -- DEF(TOK_free, "free") -- DEF(TOK_realloc, "realloc") -+ DEF(TOK_malloc, "ckalloc") -+ DEF(TOK_free, "ckfree") -+ DEF(TOK_realloc, "ckrealloc") - DEF(TOK_memalign, "memalign") - DEF(TOK_calloc, "calloc") - DEF(TOK_memmove, "memmove") - DEF(TOK_strlen, "strlen") - DEF(TOK_strcpy, "strcpy") -- DEF(TOK__alloca, "_alloca") - #endif - - /* Tiny Assembler */ -@@ -444,7 +444,7 @@ - #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) - #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) - #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) --#include "i386-asm.h" -+#include "i386/i386-asm.h" - - #define ALT(x) - #define DEF_ASM_OP0(name, opcode) -@@ -452,6 +452,6 @@ - #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name) - #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name) - #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name) --#include "i386-asm.h" -+#include "i386/i386-asm.h" - - #endif ---- tcc-0.9.24/VERSION 2008-03-31 03:24:00.000000000 -0400 -+++ tcltcc-0.4/demo/expat/VERSION 2007-11-07 10:04:16.000000000 -0500 -@@ -1 +1 @@ --0.9.24 -\ No newline at end of file -+expat-2.0.1