aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile39
-rw-r--r--arm-gen.c70
-rw-r--r--c67-gen.c95
-rw-r--r--i386-asm.c20
-rw-r--r--i386-gen.c78
-rw-r--r--libtcc.c732
-rw-r--r--tcc.c32
-rw-r--r--tcc.h434
-rw-r--r--tccasm.c18
-rw-r--r--tcccoff.c4
-rw-r--r--tccelf.c62
-rw-r--r--tccgen.c342
-rw-r--r--tccpe.c129
-rw-r--r--tccpp.c221
-rw-r--r--tccrun.c43
-rw-r--r--x86_64-gen.c38
16 files changed, 1317 insertions, 1040 deletions
diff --git a/Makefile b/Makefile
index 08ef48a..b27e5fa 100644
--- a/Makefile
+++ b/Makefile
@@ -113,11 +113,13 @@ ifdef CONFIG_CROSS
PROGS+=$(PROGS_CROSS)
endif
+# NOTALLINONE = 1
+
all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF)
# Host Tiny C Compiler
-tcc$(EXESUF): $(NATIVE_FILES)
- $(CC) -o $@ $< $(NATIVE_TARGET) $(CFLAGS) $(LIBS)
+tcc$(EXESUF): tcc.o libtcc.a
+ $(CC) -o $@ $^ $(LIBS)
# Cross Tiny C Compilers
i386-tcc$(EXESUF): $(I386_FILES)
@@ -151,10 +153,22 @@ arm-tcc-vfp-eabi$(EXESUF): $(ARM_FILES)
$(CC) -o $@ $< -DTCC_TARGET_ARM -DTCC_ARM_EABI $(CFLAGS) $(LIBS)
# libtcc generation and test
-libtcc.o: $(NATIVE_FILES)
- $(CC) -o $@ -c libtcc.c $(NATIVE_TARGET) $(CFLAGS)
-libtcc.a: libtcc.o
+ifdef NOTALLINONE
+LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
+LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
+$(LIBTCC_OBJ) : DEFINES += -DNOTALLINONE
+else
+LIBTCC_OBJ = libtcc.o
+LIBTCC_INC = $(NATIVE_FILES)
+endif
+
+tcc.o : DEFINES += -DNOTALLINONE
+
+$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
+ $(CC) -o $@ -c $< $(NATIVE_TARGET) $(CFLAGS) $(DEFINES)
+
+libtcc.a: $(LIBTCC_OBJ)
$(AR) rcs $@ $^
libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a
@@ -260,19 +274,18 @@ tar:
rm -rf /tmp/$(TCC-VERSION)
# in tests subdir
-test clean:
+%est:
$(MAKE) -C tests $@
-config.mak:
- @echo Running configure ...
- @./configure
-
-# clean
-clean: local_clean
-local_clean:
+clean:
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.out libtcc_test$(EXESUF)
+ $(MAKE) -C tests $@
distclean: clean
rm -vf config.h config.mak config.texi tcc.1
+config.mak:
+ @echo Running configure ...
+ @./configure
+
endif # ifeq ($(TOP),.)
diff --git a/arm-gen.c b/arm-gen.c
index e0866ff..e9bc3a0 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -20,11 +20,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef TARGET_DEFS_ONLY
+
#ifdef TCC_ARM_EABI
#define TCC_ARM_VFP
#endif
-
/* number of available registers */
#ifdef TCC_ARM_VFP
#define NB_REGS 13
@@ -75,32 +76,6 @@ enum {
#endif
};
-const int reg_classes[NB_REGS] = {
- /* r0 */ RC_INT | RC_R0,
- /* r1 */ RC_INT | RC_R1,
- /* r2 */ RC_INT | RC_R2,
- /* r3 */ RC_INT | RC_R3,
- /* r12 */ RC_INT | RC_R12,
- /* f0 */ RC_FLOAT | RC_F0,
- /* f1 */ RC_FLOAT | RC_F1,
- /* f2 */ RC_FLOAT | RC_F2,
- /* f3 */ RC_FLOAT | RC_F3,
-#ifdef TCC_ARM_VFP
- /* d4/s8 */ RC_FLOAT | RC_F4,
-/* d5/s10 */ RC_FLOAT | RC_F5,
-/* d6/s12 */ RC_FLOAT | RC_F6,
-/* d7/s14 */ RC_FLOAT | RC_F7,
-#endif
-};
-
-static int two2mask(int a,int b) {
- return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
-}
-
-static int regmask(int r) {
- return reg_classes[r]&~(RC_INT|RC_FLOAT);
-}
-
#ifdef TCC_ARM_VFP
#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
#endif
@@ -171,10 +146,42 @@ static CType float_type, double_type, func_float_type, func_double_type;
#define ELF_PAGE_SIZE 0x1000
/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* r0 */ RC_INT | RC_R0,
+ /* r1 */ RC_INT | RC_R1,
+ /* r2 */ RC_INT | RC_R2,
+ /* r3 */ RC_INT | RC_R3,
+ /* r12 */ RC_INT | RC_R12,
+ /* f0 */ RC_FLOAT | RC_F0,
+ /* f1 */ RC_FLOAT | RC_F1,
+ /* f2 */ RC_FLOAT | RC_F2,
+ /* f3 */ RC_FLOAT | RC_F3,
+#ifdef TCC_ARM_VFP
+ /* d4/s8 */ RC_FLOAT | RC_F4,
+/* d5/s10 */ RC_FLOAT | RC_F5,
+/* d6/s12 */ RC_FLOAT | RC_F6,
+/* d7/s14 */ RC_FLOAT | RC_F7,
+#endif
+};
+
static unsigned long func_sub_sp_offset,last_itod_magic;
static int leaffunc;
-void o(unsigned long i)
+static int two2mask(int a,int b) {
+ return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
+}
+
+static int regmask(int r) {
+ return reg_classes[r]&~(RC_INT|RC_FLOAT);
+}
+
+/******************************************************/
+
+void o(unsigned int i)
{
/* this is a good place to start adding big-endian support*/
int ind1;
@@ -304,7 +311,7 @@ void stuff_const_harder(unsigned long op,unsigned long v) {
}
}
-unsigned long encbranch(int pos,int addr,int fail)
+ST_FUNC unsigned long encbranch(int pos,int addr,int fail)
{
addr-=pos+8;
addr/=4;
@@ -1571,7 +1578,7 @@ void gen_opf(int op)
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
and 'long long' cases. */
-void gen_cvt_itof1(int t)
+ST_FUNC void gen_cvt_itof1(int t)
{
int r,r2,bt;
bt=vtop->type.t & VT_BTYPE;
@@ -1732,4 +1739,5 @@ void ggoto(void)
/* end of ARM code generator */
/*************************************************************/
-
+#endif
+/*************************************************************/
diff --git a/c67-gen.c b/c67-gen.c
index 88224fd..b353194 100644
--- a/c67-gen.c
+++ b/c67-gen.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef TARGET_DEFS_ONLY
+
//#define ASSEMBLY_LISTING_C67
/* number of available registers */
@@ -85,62 +87,18 @@ enum {
TREG_C67_B13,
};
-const int reg_classes[NB_REGS] = {
- /* eax */ RC_INT | RC_FLOAT | RC_EAX,
- // only allow even regs for floats (allow for doubles)
- /* ecx */ RC_INT | RC_ECX,
- /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
- // only allow even regs for floats (allow for doubles)
- /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
- /* A4 */ RC_C67_A4,
- /* A5 */ RC_C67_A5,
- /* B4 */ RC_C67_B4,
- /* B5 */ RC_C67_B5,
- /* A6 */ RC_C67_A6,
- /* A7 */ RC_C67_A7,
- /* B6 */ RC_C67_B6,
- /* B7 */ RC_C67_B7,
- /* A8 */ RC_C67_A8,
- /* A9 */ RC_C67_A9,
- /* B8 */ RC_C67_B8,
- /* B9 */ RC_C67_B9,
- /* A10 */ RC_C67_A10,
- /* A11 */ RC_C67_A11,
- /* B10 */ RC_C67_B10,
- /* B11 */ RC_C67_B11,
- /* A12 */ RC_C67_A10,
- /* A13 */ RC_C67_A11,
- /* B12 */ RC_C67_B10,
- /* B13 */ RC_C67_B11
-};
-
/* return registers for function */
#define REG_IRET TREG_C67_A4 /* single word int return register */
#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */
#define REG_FRET TREG_C67_A4 /* float return register */
-
#define ALWAYS_ASSERT(x) \
do {\
if (!(x))\
error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
} while (0)
-// although tcc thinks it is passing parameters on the stack,
-// the C67 really passes up to the first 10 params in special
-// regs or regs pairs (for 64 bit params). So keep track of
-// the stack offsets so we can translate to the appropriate
-// reg (pair)
-
-
-#define NoCallArgsPassedOnStack 10
-int NoOfCurFuncArgs;
-int TranslateStackToReg[NoCallArgsPassedOnStack];
-int ParamLocOnStack[NoCallArgsPassedOnStack];
-int TotalBytesPushedOnStack;
-
/* defined if function parameters must be evaluated in reverse order */
-
//#define INVERT_FUNC_PARAMS
/* defined if structures are passed as pointers. Otherwise structures
@@ -171,7 +129,52 @@ int TotalBytesPushedOnStack;
#define ELF_PAGE_SIZE 0x1000
/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* eax */ RC_INT | RC_FLOAT | RC_EAX,
+ // only allow even regs for floats (allow for doubles)
+ /* ecx */ RC_INT | RC_ECX,
+ /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
+ // only allow even regs for floats (allow for doubles)
+ /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
+ /* A4 */ RC_C67_A4,
+ /* A5 */ RC_C67_A5,
+ /* B4 */ RC_C67_B4,
+ /* B5 */ RC_C67_B5,
+ /* A6 */ RC_C67_A6,
+ /* A7 */ RC_C67_A7,
+ /* B6 */ RC_C67_B6,
+ /* B7 */ RC_C67_B7,
+ /* A8 */ RC_C67_A8,
+ /* A9 */ RC_C67_A9,
+ /* B8 */ RC_C67_B8,
+ /* B9 */ RC_C67_B9,
+ /* A10 */ RC_C67_A10,
+ /* A11 */ RC_C67_A11,
+ /* B10 */ RC_C67_B10,
+ /* B11 */ RC_C67_B11,
+ /* A12 */ RC_C67_A10,
+ /* A13 */ RC_C67_A11,
+ /* B12 */ RC_C67_B10,
+ /* B13 */ RC_C67_B11
+};
+
+// although tcc thinks it is passing parameters on the stack,
+// the C67 really passes up to the first 10 params in special
+// regs or regs pairs (for 64 bit params). So keep track of
+// the stack offsets so we can translate to the appropriate
+// reg (pair)
+
+#define NoCallArgsPassedOnStack 10
+int NoOfCurFuncArgs;
+int TranslateStackToReg[NoCallArgsPassedOnStack];
+int ParamLocOnStack[NoCallArgsPassedOnStack];
+int TotalBytesPushedOnStack;
+/******************************************************/
static unsigned long func_sub_sp_offset;
static int func_ret_sub;
@@ -2545,5 +2548,7 @@ void ggoto(void)
vtop--;
}
-/* end of X86 code generator */
+/* end of C67 code generator */
+/*************************************************************/
+#endif
/*************************************************************/
diff --git a/i386-asm.c b/i386-asm.c
index 6e1314c..a378191 100644
--- a/i386-asm.c
+++ b/i386-asm.c
@@ -19,7 +19,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "tcc.h"
+
+// #define NB_ASM_REGS 8
#define MAX_OPERANDS 3
+#define NB_SAVED_REGS 3
#define TOK_ASM_first TOK_ASM_clc
#define TOK_ASM_last TOK_ASM_emms
@@ -398,7 +402,8 @@ static void parse_operand(TCCState *s1, Operand *op)
op->type |= indir;
}
-static void gen_expr32(ExprValue *pe)
+/* XXX: unify with C code output ? */
+ST_FUNC void gen_expr32(ExprValue *pe)
{
gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
}
@@ -554,7 +559,7 @@ static inline void asm_modrm(int reg, Operand *op)
}
}
-static void asm_opcode(TCCState *s1, int opcode)
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
{
const ASMInstr *pa;
int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
@@ -966,9 +971,6 @@ static void asm_opcode(TCCState *s1, int opcode)
#endif
}
-#define NB_SAVED_REGS 3
-#define NB_ASM_REGS 8
-
/* return the constraint priority (we allocate first the lowest
numbered constraints) */
static inline int constraint_priority(const char *str)
@@ -1030,7 +1032,7 @@ static const char *skip_constraint_modifiers(const char *p)
#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
-static void asm_compute_constraints(ASMOperand *operands,
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
int nb_operands, int nb_outputs,
const uint8_t *clobber_regs,
int *pout_reg)
@@ -1262,7 +1264,7 @@ static void asm_compute_constraints(ASMOperand *operands,
#endif
}
-static void subst_asm_operand(CString *add_str,
+ST_FUNC void subst_asm_operand(CString *add_str,
SValue *sv, int modifier)
{
int r, reg, size, val;
@@ -1356,7 +1358,7 @@ static void subst_asm_operand(CString *add_str,
}
/* generate prolog and epilog code for asm statment */
-static void asm_gen_code(ASMOperand *operands, int nb_operands,
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
int nb_outputs, int is_output,
uint8_t *clobber_regs,
int out_reg)
@@ -1450,7 +1452,7 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands,
}
}
-static void asm_clobber(uint8_t *clobber_regs, const char *str)
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
{
int reg;
TokenSym *ts;
diff --git a/i386-gen.c b/i386-gen.c
index 161be93..9a8ceee 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -18,8 +18,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef TARGET_DEFS_ONLY
+
/* number of available registers */
-#define NB_REGS 4
+#define NB_REGS 4
+#define NB_ASM_REGS 8
/* a register can belong to several classes. The classes must be
sorted from more general to more precise (see gv2() code which does
@@ -42,13 +45,6 @@ enum {
TREG_ST0,
};
-const int reg_classes[NB_REGS] = {
- /* eax */ RC_INT | RC_EAX,
- /* ecx */ RC_INT | RC_ECX,
- /* edx */ RC_INT | RC_EDX,
- /* st0 */ RC_FLOAT | RC_ST0,
-};
-
/* return registers for function */
#define REG_IRET TREG_EAX /* single word int return register */
#define REG_LRET TREG_EDX /* second word return register (for long long) */
@@ -70,6 +66,9 @@ const int reg_classes[NB_REGS] = {
/* maximum alignment (for aligned attribute support) */
#define MAX_ALIGN 8
+
+#define psym oad
+
/******************************************************/
/* ELF defines */
@@ -85,6 +84,16 @@ const int reg_classes[NB_REGS] = {
#define ELF_PAGE_SIZE 0x1000
/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* eax */ RC_INT | RC_EAX,
+ /* ecx */ RC_INT | RC_ECX,
+ /* edx */ RC_INT | RC_EDX,
+ /* st0 */ RC_FLOAT | RC_ST0,
+};
static unsigned long func_sub_sp_offset;
static int func_ret_sub;
@@ -93,7 +102,7 @@ static unsigned long func_bound_offset;
#endif
/* XXX: make it faster ? */
-void g(int c)
+ST_FUNC void g(int c)
{
int ind1;
ind1 = ind + 1;
@@ -103,7 +112,7 @@ void g(int c)
ind = ind1;
}
-void o(unsigned int c)
+ST_FUNC void o(unsigned int c)
{
while (c) {
g(c);
@@ -111,13 +120,13 @@ void o(unsigned int c)
}
}
-void gen_le16(int v)
+ST_FUNC void gen_le16(int v)
{
g(v);
g(v >> 8);
}
-void gen_le32(int c)
+ST_FUNC void gen_le32(int c)
{
g(c);
g(c >> 8);
@@ -126,7 +135,7 @@ void gen_le32(int c)
}
/* output a symbol and patch all calls to it */
-void gsym_addr(int t, int a)
+ST_FUNC void gsym_addr(int t, int a)
{
int n, *ptr;
while (t) {
@@ -137,7 +146,7 @@ void gsym_addr(int t, int a)
}
}
-void gsym(int t)
+ST_FUNC void gsym(int t)
{
gsym_addr(t, ind);
}
@@ -147,7 +156,7 @@ void gsym(int t)
#define psym oad
/* instruction + 4 bytes data. Return the address of the data */
-static int oad(int c, int s)
+ST_FUNC int oad(int c, int s)
{
int ind1;
@@ -162,14 +171,14 @@ static int oad(int c, int s)
}
/* output constant with relocation if 'r & VT_SYM' is true */
-static void gen_addr32(int r, Sym *sym, int c)
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_386_32);
gen_le32(c);
}
-static void gen_addrpc32(int r, Sym *sym, int c)
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_386_PC32);
@@ -200,7 +209,7 @@ static void gen_modrm(int op_reg, int r, Sym *sym, int c)
}
/* load 'r' from value 'sv' */
-void load(int r, SValue *sv)
+ST_FUNC void load(int r, SValue *sv)
{
int v, t, ft, fc, fr;
SValue v1;
@@ -269,7 +278,7 @@ void load(int r, SValue *sv)
}
/* store register 'r' in lvalue 'v' */
-void store(int r, SValue *v)
+ST_FUNC void store(int r, SValue *v)
{
int fr, bt, ft, fc;
@@ -349,7 +358,7 @@ static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
/* 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)
+ST_FUNC void gfunc_call(int nb_args)
{
int size, align, r, args_size, i, func_call;
Sym *func_sym;
@@ -442,7 +451,7 @@ void gfunc_call(int nb_args)
#endif
/* generate function prolog of type 't' */
-void gfunc_prolog(CType *func_type)
+ST_FUNC void gfunc_prolog(CType *func_type)
{
int addr, align, size, func_call, fastcall_nb_regs;
int param_index, param_addr;
@@ -524,7 +533,7 @@ void gfunc_prolog(CType *func_type)
}
/* generate function epilog */
-void gfunc_epilog(void)
+ST_FUNC void gfunc_epilog(void)
{
int v, saved_ind;
@@ -595,13 +604,13 @@ void gfunc_epilog(void)
}
/* generate a jump to a label */
-int gjmp(int t)
+ST_FUNC int gjmp(int t)
{
return psym(0xe9, t);
}
/* generate a jump to a fixed address */
-void gjmp_addr(int a)
+ST_FUNC void gjmp_addr(int a)
{
int r;
r = a - ind - 2;
@@ -614,7 +623,7 @@ void gjmp_addr(int a)
}
/* generate a test. set 'inv' to invert test. Stack entry is popped */
-int gtst(int inv, int t)
+ST_FUNC int gtst(int inv, int t)
{
int v, *p;
@@ -659,7 +668,7 @@ int gtst(int inv, int t)
}
/* generate an integer binary operation */
-void gen_opi(int op)
+ST_FUNC void gen_opi(int op)
{
int r, fr, opc, c;
@@ -793,7 +802,7 @@ void gen_opi(int op)
/* 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)
+ST_FUNC void gen_opf(int op)
{
int a, ft, fc, swapped, r;
@@ -905,7 +914,7 @@ void gen_opf(int op)
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
and 'long long' cases. */
-void gen_cvt_itof(int t)
+ST_FUNC void gen_cvt_itof(int t)
{
save_reg(TREG_ST0);
gv(RC_INT);
@@ -935,7 +944,7 @@ void gen_cvt_itof(int t)
/* convert fp to int 't' type */
/* XXX: handle long long case */
-void gen_cvt_ftoi(int t)
+ST_FUNC void gen_cvt_ftoi(int t)
{
int r, r2, size;
Sym *sym;
@@ -986,14 +995,14 @@ void gen_cvt_ftoi(int t)
}
/* convert from one floating point type to another */
-void gen_cvt_ftof(int t)
+ST_FUNC void gen_cvt_ftof(int t)
{
/* all we have to do on i386 is to put the float in a register */
gv(RC_FLOAT);
}
/* computed goto support */
-void ggoto(void)
+ST_FUNC void ggoto(void)
{
gcall_or_jmp(1);
vtop--;
@@ -1003,7 +1012,7 @@ void ggoto(void)
#ifdef CONFIG_TCC_BCHECK
/* generate a bounded pointer addition */
-void gen_bounded_ptr_add(void)
+ST_FUNC void gen_bounded_ptr_add(void)
{
Sym *sym;
@@ -1026,7 +1035,7 @@ void gen_bounded_ptr_add(void)
/* patch pointer addition in vtop so that pointer dereferencing is
also tested */
-void gen_bounded_ptr_deref(void)
+ST_FUNC void gen_bounded_ptr_deref(void)
{
int func;
int size, align;
@@ -1068,4 +1077,5 @@ void gen_bounded_ptr_deref(void)
/* end of X86 code generator */
/*************************************************************/
-
+#endif
+/*************************************************************/
diff --git a/libtcc.c b/libtcc.c
index 7ef1f0b..9be8c1c 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -23,344 +23,70 @@
/********************************************************/
/* global variables */
-/* display benchmark infos */
-int total_lines;
-int total_bytes;
-
-/* parser */
-static struct BufferedFile *file;
-static int ch, 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 */
-#define TOK_FLAG_EOF 0x0008 /* end of file */
-
-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 */
-#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
-
-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
-
-#ifdef CONFIG_TCC_BCHECK
-/* bound check related sections */
-static Section *bounds_section; /* contains global data bound description */
-static Section *lbounds_section; /* contains local data bound description */
-#endif
-
-/* symbol sections */
-static Section *symtab_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;
-/* 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;
-static TokenSym *hash_ident[TOK_HASH_SIZE];
-static char token_buf[STRING_MAX_SIZE + 1];
-static char *funcname;
-static Sym *global_stack, *local_stack;
-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 void **sym_pools;
-static int nb_sym_pools;
-
-static SValue vstack[VSTACK_SIZE], *vtop;
-/* some predefined types */
-static CType char_pointer_type, func_old_type, int_type;
-
/* use GNU C extensions */
-static int gnu_ext = 1;
-
-/* use Tiny C extensions */
-static int tcc_ext = 1;
+ST_DATA int gnu_ext = 1;
-/* max number of callers shown if error */
-#ifdef CONFIG_TCC_BACKTRACE
-int num_callers = 6;
-void *rt_prog_main;
-const char **rt_bound_error_msg;
-#endif
+/* use TinyCC extensions */
+ST_DATA int tcc_ext = 1;
/* XXX: get rid of this ASAP */
-static struct TCCState *tcc_state;
-
-/********************************************************/
-/* function prototypes */
-
-/* tccpp.c */
-static void next(void);
-char *get_tok_str(int v, CValue *cv);
-
-/* tccgen.c */
-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);
-
-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 compare_types(CType *type1, CType *type2, int unqualified);
-static int is_compatible_types(CType *type1, CType *type2);
-static int is_compatible_parameter_types(CType *type1, CType *type2);
-
-int ieee_finite(double d);
-void vpushi(int v);
-void vpushll(long long 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);
-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, uplong 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 */
-#define AFF_PREPROCESS 0x0004 /* preprocess file */
-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 */
-int pe_load_file(struct TCCState *s1, const char *filename, int fd);
-int pe_output_file(struct TCCState *s1, const char *filename);
-int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv));
-
-/* tccasm.c */
-#ifdef CONFIG_TCC_ASM
-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);
+ST_DATA struct TCCState *tcc_state;
-static int tcc_assemble(TCCState *s1, int do_preprocess);
+#ifdef CONFIG_TCC_BACKTRACE
+ST_DATA int num_callers = 6;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
#endif
-static void asm_instr(void);
-static void asm_global_instr(void);
-
-/********************************************************/
-/* libtcc.c */
-
-static Sym *__sym_malloc(void);
-static inline Sym *sym_malloc(void);
-static inline void sym_free(Sym *sym);
-Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
-static void free_section(Section *s);
-static void section_realloc(Section *sec, unsigned long new_size);
-static void *section_ptr_add(Section *sec, unsigned long size);
-Section *find_section(TCCState *s1, const char *name);
-static void put_extern_sym2(
- Sym *sym, Section *section,
- unsigned long value, unsigned long size, int can_add_underscore);
-static void put_extern_sym(
- Sym *sym, Section *section,
- unsigned long value, unsigned long size);
-static void greloc(Section *s, Sym *sym, unsigned long offset, int type);
-
-static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap);
-static void strcat_printf(char *buf, int buf_size, const char *fmt, ...);
-
-/* CString handling */
-static void cstr_realloc(CString *cstr, int new_size);
-static inline void cstr_ccat(CString *cstr, int ch);
-static void cstr_cat(CString *cstr, const char *str);
-static void cstr_wccat(CString *cstr, int ch);
-static void cstr_new(CString *cstr);
-static void cstr_free(CString *cstr);
-#define cstr_reset(cstr) cstr_free(cstr)
-static void add_char(CString *cstr, int c);
-
-static Sym *sym_push2(Sym **ps, int v, int t, long c);
-static Sym *sym_find2(Sym *s, int v);
-static inline Sym *struct_find(int v);
-static inline Sym *sym_find(int v);
-static Sym *sym_push(int v, CType *type, int r, int c);
-static Sym *global_identifier_push(int v, int t, int c);
-static void sym_pop(Sym **ptop, Sym *b);
-
-BufferedFile *tcc_open(TCCState *s1, const char *filename);
-void tcc_close(BufferedFile *bf);
-static int tcc_compile(TCCState *s1);
-
-void expect(const char *msg);
-void skip(int c);
-static void test_lvalue(void);
-void *resolve_sym(TCCState *s1, const char *sym);
-
-static inline int isid(int c)
-{
- return (c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || c == '_';
-}
-
-static inline int isnum(int c)
-{
- return c >= '0' && c <= '9';
-}
-
-static inline int isoct(int c)
-{
- return c >= '0' && c <= '7';
-}
-
-static inline int toup(int c)
-{
- if (c >= 'a' && c <= 'z')
- return c - 'a' + 'A';
- else
- return c;
-}
-
/********************************************************/
+#ifndef NOTALLINONE
+#include "tccpp.c"
+#include "tccgen.c"
+#include "tccelf.c"
+#include "tccrun.c"
#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 TCC_TARGET_X86_64
#include "x86_64-gen.c"
#endif
-
-#include "tccpp.c"
-#include "tccgen.c"
-
#ifdef CONFIG_TCC_ASM
-
+#include "tccasm.c"
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
#include "i386-asm.c"
#endif
-
-#include "tccasm.c"
-#else
-static void asm_instr(void)
-{
- error("inline asm() not supported");
-}
-static void asm_global_instr(void)
-{
- error("inline asm() not supported");
-}
#endif
-
-#include "tccelf.c"
-
#ifdef TCC_TARGET_COFF
#include "tcccoff.c"
#endif
-
#ifdef TCC_TARGET_PE
#include "tccpe.c"
#endif
+#endif /* ALL_IN_ONE */
-#include "tccrun.c"
+/********************************************************/
+#ifndef CONFIG_TCC_ASM
+ST_FUNC void asm_instr(void)
+{
+ error("inline asm() not supported");
+}
+ST_FUNC void asm_global_instr(void)
+{
+ error("inline asm() not supported");
+}
+#endif
/********************************************************/
+
#ifdef _WIN32
-char *normalize_slashes(char *path)
+static char *normalize_slashes(char *path)
{
char *p;
for (p = path; *p; ++p)
@@ -369,10 +95,10 @@ char *normalize_slashes(char *path)
return path;
}
-HMODULE tcc_module;
+static HMODULE tcc_module;
/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
-void tcc_set_lib_path_w32(TCCState *s)
+static void tcc_set_lib_path_w32(TCCState *s)
{
char path[1024], *p;
GetModuleFileNameA(tcc_module, path, sizeof path);
@@ -396,18 +122,8 @@ BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
#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 *p = (int *)&d;
- return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
-}
-
/* copy a string and truncate it. */
-char *pstrcpy(char *buf, int buf_size, const char *s)
+PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
{
char *q, *q_end;
int c;
@@ -427,7 +143,7 @@ char *pstrcpy(char *buf, int buf_size, const char *s)
}
/* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
+PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
{
int len;
len = strlen(buf);
@@ -437,7 +153,7 @@ char *pstrcat(char *buf, int buf_size, const char *s)
}
/* extract the basename of a file */
-char *tcc_basename(const char *name)
+PUB_FUNC char *tcc_basename(const char *name)
{
char *p = strchr(name, 0);
while (p > name && !IS_PATHSEP(p[-1]))
@@ -445,21 +161,27 @@ char *tcc_basename(const char *name)
return p;
}
-char *tcc_fileextension (const char *name)
+PUB_FUNC char *tcc_fileextension (const char *name)
{
char *b = tcc_basename(name);
char *e = strrchr(b, '.');
return e ? e : strchr(b, 0);
}
+/********************************************************/
/* memory management */
+
+#undef free
+#undef malloc
+#undef realloc
+
#ifdef MEM_DEBUG
int mem_cur_size;
int mem_max_size;
unsigned malloc_usable_size(void*);
#endif
-void tcc_free(void *ptr)
+PUB_FUNC void tcc_free(void *ptr)
{
#ifdef MEM_DEBUG
mem_cur_size -= malloc_usable_size(ptr);
@@ -467,7 +189,7 @@ void tcc_free(void *ptr)
free(ptr);
}
-void *tcc_malloc(unsigned long size)
+PUB_FUNC void *tcc_malloc(unsigned long size)
{
void *ptr;
ptr = malloc(size);
@@ -481,7 +203,7 @@ void *tcc_malloc(unsigned long size)
return ptr;
}
-void *tcc_mallocz(unsigned long size)
+PUB_FUNC void *tcc_mallocz(unsigned long size)
{
void *ptr;
ptr = tcc_malloc(size);
@@ -489,7 +211,7 @@ void *tcc_mallocz(unsigned long size)
return ptr;
}
-void *tcc_realloc(void *ptr, unsigned long size)
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
{
void *ptr1;
#ifdef MEM_DEBUG
@@ -505,7 +227,7 @@ void *tcc_realloc(void *ptr, unsigned long size)
return ptr1;
}
-char *tcc_strdup(const char *str)
+PUB_FUNC char *tcc_strdup(const char *str)
{
char *ptr;
ptr = tcc_malloc(strlen(str) + 1);
@@ -513,7 +235,7 @@ char *tcc_strdup(const char *str)
return ptr;
}
-void tcc_memstats(void)
+PUB_FUNC void tcc_memstats(void)
{
#ifdef MEM_DEBUG
printf("memory in use: %d\n", mem_cur_size);
@@ -524,7 +246,10 @@ void tcc_memstats(void)
#define malloc(s) use_tcc_malloc(s)
#define realloc(p, s) use_tcc_realloc(p, s)
-void dynarray_add(void ***ptab, int *nb_ptr, void *data)
+/********************************************************/
+/* dynarrays */
+
+PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
{
int nb, nb_alloc;
void **pp;
@@ -546,7 +271,7 @@ void dynarray_add(void ***ptab, int *nb_ptr, void *data)
*nb_ptr = nb;
}
-void dynarray_reset(void *pp, int *n)
+PUB_FUNC void dynarray_reset(void *pp, int *n)
{
void **p;
for (p = *(void***)pp; *n; ++p, --*n)
@@ -556,43 +281,18 @@ void dynarray_reset(void *pp, int *n)
*(void**)pp = NULL;
}
-/* symbol allocator */
-static Sym *__sym_malloc(void)
-{
- Sym *sym_pool, *sym, *last_sym;
- int i;
-
- sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
- dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
-
- last_sym = sym_free_first;
- sym = sym_pool;
- for(i = 0; i < SYM_POOL_NB; i++) {
- sym->next = last_sym;
- last_sym = sym;
- sym++;
- }
- sym_free_first = last_sym;
- return last_sym;
-}
-
-static inline Sym *sym_malloc(void)
+/* we use our own 'finite' function to avoid potential problems with
+ non standard math libs */
+/* XXX: endianness dependent */
+ST_FUNC int ieee_finite(double d)
{
- Sym *sym;
- sym = sym_free_first;
- if (!sym)
- sym = __sym_malloc();
- sym_free_first = sym->next;
- return sym;
+ int *p = (int *)&d;
+ return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
}
-static inline void sym_free(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)
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
{
Section *sec;
@@ -633,7 +333,7 @@ static void free_section(Section *s)
}
/* realloc section and set its content to zero */
-static void section_realloc(Section *sec, unsigned long new_size)
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
{
unsigned long size;
unsigned char *data;
@@ -653,7 +353,7 @@ static void section_realloc(Section *sec, unsigned long new_size)
/* reserve at least 'size' bytes in section 'sec' from
sec->data_offset. */
-static void *section_ptr_add(Section *sec, unsigned long size)
+ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
{
unsigned long offset, offset1;
@@ -667,7 +367,7 @@ static void *section_ptr_add(Section *sec, unsigned long size)
/* return a reference to a section, and create it if it does not
exists */
-Section *find_section(TCCState *s1, const char *name)
+ST_FUNC Section *find_section(TCCState *s1, const char *name)
{
Section *sec;
int i;
@@ -682,7 +382,7 @@ Section *find_section(TCCState *s1, const char *name)
/* 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,
+ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
unsigned long value, unsigned long size,
int can_add_underscore)
{
@@ -779,14 +479,14 @@ static void put_extern_sym2(Sym *sym, Section *section,
}
}
-static void put_extern_sym(Sym *sym, Section *section,
+ST_FUNC void put_extern_sym(Sym *sym, Section *section,
unsigned long value, unsigned long size)
{
put_extern_sym2(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)
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
{
int c = 0;
if (sym) {
@@ -798,6 +498,8 @@ static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
put_elf_reloc(symtab_section, s, offset, type, c);
}
+/********************************************************/
+
static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
{
int len;
@@ -813,7 +515,7 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
va_end(ap);
}
-void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
+static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
{
char buf[2048];
BufferedFile **f;
@@ -850,7 +552,7 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
s1->nb_errors++;
}
-void tcc_set_error_func(TCCState *s, void *error_opaque,
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
void (*error_func)(void *opaque, const char *msg))
{
s->error_opaque = error_opaque;
@@ -858,7 +560,7 @@ void tcc_set_error_func(TCCState *s, void *error_opaque,
}
/* error without aborting current compilation */
-void error_noabort(const char *fmt, ...)
+PUB_FUNC void error_noabort(const char *fmt, ...)
{
TCCState *s1 = tcc_state;
va_list ap;
@@ -868,7 +570,7 @@ void error_noabort(const char *fmt, ...)
va_end(ap);
}
-void error(const char *fmt, ...)
+PUB_FUNC void error(const char *fmt, ...)
{
TCCState *s1 = tcc_state;
va_list ap;
@@ -885,12 +587,12 @@ void error(const char *fmt, ...)
}
}
-void expect(const char *msg)
+PUB_FUNC void expect(const char *msg)
{
error("%s expected", msg);
}
-void warning(const char *fmt, ...)
+PUB_FUNC void warning(const char *fmt, ...)
{
TCCState *s1 = tcc_state;
va_list ap;
@@ -903,233 +605,10 @@ void warning(const char *fmt, ...)
va_end(ap);
}
-void skip(int c)
-{
- if (tok != c)
- error("'%c' expected", c);
- next();
-}
-
-static void test_lvalue(void)
-{
- if (!(vtop->r & VT_LVAL))
- expect("lvalue");
-}
-
-/* CString handling */
-
-static void cstr_realloc(CString *cstr, int new_size)
-{
- int size;
- void *data;
-
- size = cstr->size_allocated;
- if (size == 0)
- 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);
- if (!data)
- error("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)
-{
- int size;
- size = cstr->size + 1;
- if (size > cstr->size_allocated)
- cstr_realloc(cstr, size);
- ((unsigned char *)cstr->data)[size - 1] = ch;
- cstr->size = size;
-}
-
-static void cstr_cat(CString *cstr, const char *str)
-{
- int c;
- for(;;) {
- c = *str;
- if (c == '\0')
- break;
- cstr_ccat(cstr, c);
- str++;
- }
-}
-
-/* add a wide char */
-static void cstr_wccat(CString *cstr, int ch)
-{
- int size;
- size = cstr->size + sizeof(nwchar_t);
- if (size > cstr->size_allocated)
- cstr_realloc(cstr, size);
- *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
- cstr->size = size;
-}
-
-static void cstr_new(CString *cstr)
-{
- memset(cstr, 0, sizeof(CString));
-}
-
-/* free string and reset it to NULL */
-static void cstr_free(CString *cstr)
-{
- tcc_free(cstr->data_allocated);
- cstr_new(cstr);
-}
-
-#define cstr_reset(cstr) cstr_free(cstr)
-
-/* XXX: unicode ? */
-static void add_char(CString *cstr, int c)
-{
- if (c == '\'' || c == '\"' || c == '\\') {
- /* XXX: could be more precise if char or string */
- cstr_ccat(cstr, '\\');
- }
- if (c >= 32 && c <= 126) {
- cstr_ccat(cstr, c);
- } else {
- cstr_ccat(cstr, '\\');
- if (c == '\n') {
- cstr_ccat(cstr, 'n');
- } else {
- cstr_ccat(cstr, '0' + ((c >> 6) & 7));
- cstr_ccat(cstr, '0' + ((c >> 3) & 7));
- cstr_ccat(cstr, '0' + (c & 7));
- }
- }
-}
-
-/* push, without hashing */
-static Sym *sym_push2(Sym **ps, int v, int t, long c)
-{
- Sym *s;
- s = sym_malloc();
- s->v = v;
- s->type.t = t;
- s->type.ref = NULL;
-#ifdef _WIN64
- s->d = NULL;
-#endif
- s->c = c;
- s->next = NULL;
- /* add in stack */
- s->prev = *ps;
- *ps = s;
- return s;
-}
-
-/* find a symbol and return its associated structure. 's' is the top
- of the symbol stack */
-static Sym *sym_find2(Sym *s, int v)
-{
- while (s) {
- if (s->v == v)
- return s;
- s = s->prev;
- }
- return NULL;
-}
-
-/* structure lookup */
-static inline Sym *struct_find(int v)
-{
- v -= TOK_IDENT;
- if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
- return NULL;
- return table_ident[v]->sym_struct;
-}
-
-/* find an identifier */
-static inline Sym *sym_find(int v)
-{
- v -= TOK_IDENT;
- if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
- return NULL;
- return table_ident[v]->sym_identifier;
-}
-
-/* push a given symbol on the symbol stack */
-static Sym *sym_push(int v, CType *type, int r, int c)
-{
- Sym *s, **ps;
- TokenSym *ts;
-
- if (local_stack)
- ps = &local_stack;
- else
- ps = &global_stack;
- s = sym_push2(ps, v, type->t, c);
- s->type.ref = type->ref;
- s->r = r;
- /* don't record fields or anonymous symbols */
- /* XXX: simplify */
- if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
- /* record symbol in token array */
- ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
- if (v & SYM_STRUCT)
- ps = &ts->sym_struct;
- else
- ps = &ts->sym_identifier;
- s->prev_tok = *ps;
- *ps = s;
- }
- return s;
-}
-
-/* push a global identifier */
-static Sym *global_identifier_push(int v, int t, int c)
-{
- Sym *s, **ps;
- s = sym_push2(&global_stack, v, t, c);
- /* don't record anonymous symbol */
- if (v < SYM_FIRST_ANOM) {
- ps = &table_ident[v - TOK_IDENT]->sym_identifier;
- /* modify the top most local identifier, so that
- sym_identifier will point to 's' when popped */
- while (*ps != NULL)
- ps = &(*ps)->prev_tok;
- s->prev_tok = NULL;
- *ps = s;
- }
- return s;
-}
-
-/* pop symbols until top reaches 'b' */
-static void sym_pop(Sym **ptop, Sym *b)
-{
- Sym *s, *ss, **ps;
- TokenSym *ts;
- int v;
-
- s = *ptop;
- while(s != b) {
- ss = s->prev;
- v = s->v;
- /* remove symbol in token array */
- /* XXX: simplify */
- if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
- ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
- if (v & SYM_STRUCT)
- ps = &ts->sym_struct;
- else
- ps = &ts->sym_identifier;
- *ps = s->prev_tok;
- }
- sym_free(s);
- s = ss;
- }
- *ptop = b;
-}
-
+/********************************************************/
/* I/O layer */
-BufferedFile *tcc_open(TCCState *s1, const char *filename)
+ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename)
{
int fd;
BufferedFile *bf;
@@ -1159,7 +638,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename)
return bf;
}
-void tcc_close(BufferedFile *bf)
+ST_FUNC void tcc_close(BufferedFile *bf)
{
total_lines += bf->line_num;
close(bf->fd);
@@ -1272,7 +751,7 @@ static int tcc_compile(TCCState *s1)
return s1->nb_errors != 0 ? -1 : 0;
}
-int tcc_compile_string(TCCState *s, const char *str)
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
{
BufferedFile bf1, *bf = &bf1;
int ret, len;
@@ -1301,7 +780,7 @@ int tcc_compile_string(TCCState *s, const char *str)
}
/* 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)
+LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
{
BufferedFile bf1, *bf = &bf1;
@@ -1331,7 +810,7 @@ void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
}
/* undefine a preprocessor symbol */
-void tcc_undefine_symbol(TCCState *s1, const char *sym)
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
{
TokenSym *ts;
Sym *s;
@@ -1369,7 +848,7 @@ static void tcc_cleanup(void)
macro_ptr = NULL;
}
-TCCState *tcc_new(void)
+LIBTCCAPI TCCState *tcc_new(void)
{
TCCState *s;
char buffer[100];
@@ -1477,6 +956,7 @@ TCCState *tcc_new(void)
".dynstrtab",
".dynhashtab", SHF_PRIVATE);
s->alacarte_link = 1;
+ s->nocommon = 1;
#ifdef CHAR_IS_UNSIGNED
s->char_is_unsigned = 1;
@@ -1485,17 +965,15 @@ TCCState *tcc_new(void)
/* XXX: currently the PE linker is not ready to support that */
s->leading_underscore = 1;
#endif
-
if (s->section_align == 0)
s->section_align = ELF_PAGE_SIZE;
-
#ifdef TCC_TARGET_I386
s->seg_size = 32;
#endif
return s;
}
-void tcc_delete(TCCState *s1)
+LIBTCCAPI void tcc_delete(TCCState *s1)
{
int i;
@@ -1533,7 +1011,7 @@ void tcc_delete(TCCState *s1)
tcc_free(s1);
}
-int tcc_add_include_path(TCCState *s1, const char *pathname)
+LIBTCCAPI int tcc_add_include_path(TCCState *s1, const char *pathname)
{
char *pathname1;
@@ -1542,7 +1020,7 @@ int tcc_add_include_path(TCCState *s1, const char *pathname)
return 0;
}
-int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
{
char *pathname1;
@@ -1668,7 +1146,7 @@ the_end:
return ret;
}
-int tcc_add_file(TCCState *s, const char *filename)
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
{
if (s->output_type == TCC_OUTPUT_PREPROCESS)
return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
@@ -1676,7 +1154,7 @@ int tcc_add_file(TCCState *s, const char *filename)
return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
}
-int tcc_add_library_path(TCCState *s, const char *pathname)
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
{
char *pathname1;
@@ -1687,7 +1165,7 @@ int tcc_add_library_path(TCCState *s, const char *pathname)
/* find and load a dll. Return non zero if not found */
/* XXX: add '-rpath' option support ? */
-static int tcc_add_dll(TCCState *s, const char *filename, int flags)
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
{
char buf[1024];
int i;
@@ -1702,7 +1180,7 @@ static int tcc_add_dll(TCCState *s, const char *filename, int flags)
}
/* the library name is the same as the argument of the '-l' option */
-int tcc_add_library(TCCState *s, const char *libraryname)
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
{
char buf[1024];
int i;
@@ -1728,7 +1206,7 @@ int tcc_add_library(TCCState *s, const char *libraryname)
return -1;
}
-int tcc_add_symbol(TCCState *s, const char *name, void *val)
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val)
{
add_elf_sym(symtab_section, (uplong)val, 0,
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
@@ -1736,7 +1214,7 @@ int tcc_add_symbol(TCCState *s, const char *name, void *val)
return 0;
}
-int tcc_set_output_type(TCCState *s, int output_type)
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
{
char buf[1024];
@@ -1825,7 +1303,7 @@ static const FlagDef warning_defs[] = {
"implicit-function-declaration" },
};
-static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
+ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
const char *name, int value)
{
int i;
@@ -1849,9 +1327,8 @@ static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
return 0;
}
-
/* set/reset a warning */
-int tcc_set_warning(TCCState *s, const char *warning_name, int value)
+LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value)
{
int i;
const FlagDef *p;
@@ -1876,20 +1353,13 @@ static const FlagDef flag_defs[] = {
};
/* set/reset a flag */
-int tcc_set_flag(TCCState *s, const char *flag_name, int value)
+PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value)
{
return set_flag(s, flag_defs, countof(flag_defs),
flag_name, value);
}
-/* set CONFIG_TCCDIR at runtime */
-void tcc_set_lib_path(TCCState *s, const char *path)
-{
- tcc_free(s->tcc_lib_path);
- s->tcc_lib_path = tcc_strdup(path);
-}
-
-void tcc_print_stats(TCCState *s, int64_t total_time)
+PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
{
double tt;
tt = (double)total_time / 1000000.0;
@@ -1902,3 +1372,17 @@ void tcc_print_stats(TCCState *s, int64_t total_time)
tt, (int)(total_lines / tt),
total_bytes / tt / 1000000.0);
}
+
+/* set CONFIG_TCCDIR at runtime */
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
+{
+ tcc_free(s->tcc_lib_path);
+ s->tcc_lib_path = tcc_strdup(path);
+}
+
+PUB_FUNC void set_num_callers(int n)
+{
+#ifdef CONFIG_TCC_BACKTRACE
+ num_callers = n;
+#endif
+}
diff --git a/tcc.c b/tcc.c
index aeda468..6c12b20 100644
--- a/tcc.c
+++ b/tcc.c
@@ -18,13 +18,25 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifdef TCC_USE_LIBTCC
+#if defined NOTALLINONE || defined TCC_USE_LIBTCC
#include "tcc.h"
#else
#include "libtcc.c"
#endif
-void help(void)
+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;
+static int do_bench = 0;
+
+#define TCC_OPTION_HAS_ARG 0x0001
+#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
+
+static void help(void)
{
printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
"usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
@@ -65,18 +77,6 @@ void help(void)
);
}
-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;
-static int do_bench = 0;
-
-#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;
@@ -213,7 +213,7 @@ static int expand_args(char ***pargv, const char *str)
return argc;
}
-int parse_args(TCCState *s, int argc, char **argv)
+static int parse_args(TCCState *s, int argc, char **argv)
{
int optind;
const TCCOption *popt;
@@ -304,7 +304,7 @@ int parse_args(TCCState *s, int argc, char **argv)
break;
#ifdef CONFIG_TCC_BACKTRACE
case TCC_OPTION_bt:
- num_callers = atoi(optarg);
+ set_num_callers(atoi(optarg));
break;
#endif
#ifdef CONFIG_TCC_BCHECK
diff --git a/tcc.h b/tcc.h
index 16aba53..ea4ae21 100644
--- a/tcc.h
+++ b/tcc.h
@@ -18,6 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifndef _TCC_H
+#define _TCC_H
+
#define _GNU_SOURCE
#include "config.h"
@@ -46,6 +49,7 @@
#include <direct.h> /* getcwd */
#define inline __inline
#define inp next_inp
+#define dlclose FreeLibrary
#ifdef _WIN64
#define uplong unsigned long long
#endif
@@ -56,6 +60,7 @@
#include <sys/time.h>
#include <sys/ucontext.h>
#include <sys/mman.h>
+#include <dlfcn.h>
#endif
#endif /* !CONFIG_TCCBOOT */
@@ -766,11 +771,11 @@ enum tcc_token {
#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
|| defined(__OpenBSD__)
/* currently incorrect */
-long double strtold(const char *nptr, char **endptr)
+static inline long double strtold(const char *nptr, char **endptr)
{
return (long double)strtod(nptr, endptr);
}
-float strtof(const char *nptr, char **endptr)
+static inline float strtof(const char *nptr, char **endptr)
{
return (float)strtod(nptr, endptr);
}
@@ -790,38 +795,411 @@ extern long double strtold (const char *__nptr, char **__endptr);
#define PATHCMP strcmp
#endif
-void error(const char *fmt, ...);
-void error_noabort(const char *fmt, ...);
-void warning(const char *fmt, ...);
-
-void tcc_set_lib_path_w32(TCCState *s);
-int tcc_set_flag(TCCState *s, const char *flag_name, int value);
-void tcc_print_stats(TCCState *s, int64_t total_time);
+/* space exlcuding newline */
+static inline int is_space(int ch)
+{
+ return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
+}
-void tcc_free(void *ptr);
-void *tcc_malloc(unsigned long size);
-void *tcc_mallocz(unsigned long size);
-void *tcc_realloc(void *ptr, unsigned long size);
-char *tcc_strdup(const char *str);
+static inline int isid(int c)
+{
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
-char *tcc_basename(const char *name);
-char *tcc_fileextension (const char *name);
-char *pstrcpy(char *buf, int buf_size, const char *s);
-char *pstrcat(char *buf, int buf_size, const char *s);
-void dynarray_add(void ***ptab, int *nb_ptr, void *data);
-void dynarray_reset(void *pp, int *n);
+static inline int isnum(int c)
+{
+ return c >= '0' && c <= '9';
+}
-/* true if float/double/long double type */
-static inline int is_float(int t)
+static inline int isoct(int c)
{
- int bt;
- bt = t & VT_BTYPE;
- return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
+ return c >= '0' && c <= '7';
}
-/* space exlcuding newline */
-static inline int is_space(int ch)
+static inline int toup(int c)
{
- return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
+ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
}
+#define PUB_FUNC
+
+#ifndef NOTALLINONE
+#define ST_INLN static inline
+#define ST_FUNC static
+#define ST_DATA static
+#else
+#define ST_INLN
+#define ST_FUNC
+#define ST_DATA extern
+#endif
+
+/* ------------ libtcc.c ------------ */
+
+/* use GNU C extensions */
+ST_DATA int gnu_ext;
+/* use Tiny C extensions */
+ST_DATA int tcc_ext;
+/* XXX: get rid of this ASAP */
+ST_DATA struct TCCState *tcc_state;
+
+#ifdef CONFIG_TCC_BACKTRACE
+ST_DATA int num_callers;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
+#endif
+
+#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
+#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
+#define AFF_PREPROCESS 0x0004 /* preprocess file */
+
+/* public functions currently used by the tcc main function */
+PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
+PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
+PUB_FUNC char *tcc_basename(const char *name);
+PUB_FUNC char *tcc_fileextension (const char *name);
+PUB_FUNC void tcc_free(void *ptr);
+PUB_FUNC void *tcc_malloc(unsigned long size);
+PUB_FUNC void *tcc_mallocz(unsigned long size);
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
+PUB_FUNC char *tcc_strdup(const char *str);
+#define free(p) use_tcc_free(p)
+#define malloc(s) use_tcc_malloc(s)
+#define realloc(p, s) use_tcc_realloc(p, s)
+#undef strdup
+#define strdup(s) use_tcc_strdup(s)
+PUB_FUNC void tcc_memstats(void);
+PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data);
+PUB_FUNC void dynarray_reset(void *pp, int *n);
+PUB_FUNC void error_noabort(const char *fmt, ...);
+PUB_FUNC void error(const char *fmt, ...);
+PUB_FUNC void expect(const char *msg);
+PUB_FUNC void warning(const char *fmt, ...);
+
+/* other utilities */
+ST_INLN void cstr_ccat(CString *cstr, int ch);
+ST_FUNC void cstr_cat(CString *cstr, const char *str);
+ST_FUNC void cstr_wccat(CString *cstr, int ch);
+ST_FUNC void cstr_new(CString *cstr);
+ST_FUNC void cstr_free(CString *cstr);
+ST_FUNC void add_char(CString *cstr, int c);
+#define cstr_reset(cstr) cstr_free(cstr)
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
+ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
+ST_FUNC Section *find_section(TCCState *s1, const char *name);
+
+ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore);
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, unsigned long value, unsigned long size);
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
+
+ST_INLN void sym_free(Sym *sym);
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
+ST_FUNC Sym *sym_find2(Sym *s, int v);
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
+ST_FUNC void sym_pop(Sym **ptop, Sym *b);
+ST_INLN Sym *struct_find(int v);
+ST_INLN Sym *sym_find(int v);
+ST_FUNC Sym *global_identifier_push(int v, int t, int c);
+
+ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename);
+ST_FUNC void tcc_close(BufferedFile *bf);
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
+PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value);
+PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time);
+PUB_FUNC void set_num_callers(int n);
+
+ST_FUNC int ieee_finite(double d);
+
+/* ------------ tccpp.c ------------ */
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA int *macro_ptr;
+ST_DATA int parse_flags;
+ST_DATA int tok_flags;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+#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 */
+#define TOK_FLAG_EOF 0x0008 /* end of file */
+
+#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 */
+#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
+
+ST_FUNC TokenSym *tok_alloc(const char *str, int len);
+ST_FUNC char *get_tok_str(int v, CValue *cv);
+ST_FUNC void save_parse_state(ParseState *s);
+ST_FUNC void restore_parse_state(ParseState *s);
+ST_INLN void tok_str_new(TokenString *s);
+ST_FUNC void tok_str_free(int *str);
+ST_FUNC void tok_str_add(TokenString *s, int t);
+ST_FUNC void tok_str_add_tok(TokenString *s);
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
+ST_FUNC void define_undef(Sym *s);
+ST_INLN Sym *define_find(int v);
+ST_FUNC void free_defines(Sym *b);
+ST_FUNC Sym *label_find(int v);
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
+ST_FUNC void label_pop(Sym **ptop, Sym *slast);
+ST_FUNC void parse_define(void);
+ST_FUNC void preprocess(int is_bof);
+ST_FUNC void next_nomacro(void);
+ST_FUNC void next(void);
+ST_INLN void unget_tok(int last_tok);
+ST_FUNC void preprocess_init(TCCState *s1);
+ST_FUNC void preprocess_new();
+ST_FUNC int tcc_preprocess(TCCState *s1);
+ST_FUNC void skip(int c);
+
+/* ------------ tccgen.c ------------ */
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section, *strtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+#define SYM_POOL_NB (8192 / sizeof(Sym))
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *local_label_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *define_stack;
+ST_DATA CType char_pointer_type, func_old_type, int_type;
+ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
+ST_DATA int rsym, anon_sym, ind, loc;
+
+ST_DATA int const_wanted; /* true if constant wanted */
+ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
+ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
+ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA char *funcname;
+
+ST_INLN int is_float(int t);
+ST_FUNC void test_lvalue(void);
+ST_FUNC void swap(int *p, int *q);
+ST_FUNC void vpushi(int v);
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
+ST_FUNC void vset(CType *type, int r, int v);
+ST_FUNC void vswap(void);
+ST_FUNC void save_reg(int r);
+ST_FUNC int get_reg(int rc);
+ST_FUNC void save_regs(int n);
+ST_FUNC int gv(int rc);
+ST_FUNC void gv2(int rc1, int rc2);
+ST_FUNC void vpop(void);
+ST_FUNC void gen_op(int op);
+ST_FUNC int type_size(CType *type, int *a);
+ST_FUNC void mk_pointer(CType *type);
+ST_FUNC void vstore(void);
+ST_FUNC void inc(int post, int c);
+ST_FUNC int lvalue_type(int t);
+ST_FUNC void indir(void);
+ST_FUNC void unary(void);
+ST_FUNC void expr_prod(void);
+ST_FUNC void expr_sum(void);
+ST_FUNC void gexpr(void);
+ST_FUNC int expr_const(void);
+ST_FUNC void gen_inline_functions(void);
+ST_FUNC void decl(int l);
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
+#endif
+
+/* ------------ tccelf.c ------------ */
+
+#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
+
+typedef struct {
+ unsigned int n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ unsigned int n_value; /* value of symbol */
+} Stab_Sym;
+
+ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
+
+ST_FUNC int put_elf_str(Section *s, const char *sym);
+ST_FUNC int put_elf_sym(Section *s, unsigned long value, unsigned long size, int info, int other, int shndx, const char *name);
+ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, int info, int other, int sh_num, const char *name);
+ST_FUNC int find_elf_sym(Section *s, const char *name);
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
+
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
+ST_FUNC void put_stabn(int type, int other, int desc, int value);
+ST_FUNC void put_stabd(int type, int other, int desc);
+
+ST_FUNC void relocate_common_syms(void);
+ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
+ST_FUNC void relocate_section(TCCState *s1, Section *s);
+
+ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
+ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
+ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
+ST_FUNC void tcc_add_bcheck(TCCState *s1);
+
+ST_FUNC void build_got_entries(TCCState *s1);
+ST_FUNC void tcc_add_runtime(TCCState *s1);
+
+#ifndef TCC_TARGET_PE
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
+ST_FUNC int tcc_load_ldscript(TCCState *s1);
+ST_FUNC uint8_t *parse_comment(uint8_t *p);
+ST_FUNC void minp(void);
+ST_INLN void inp(void);
+ST_FUNC int handle_eob(void);
+#endif
+
+/* ------------ xxx-gen.c ------------ */
+
+ST_FUNC void gsym_addr(int t, int a);
+ST_FUNC void gsym(int t);
+ST_FUNC void load(int r, SValue *sv);
+ST_FUNC void store(int r, SValue *v);
+ST_FUNC void gfunc_call(int nb_args);
+ST_FUNC void gfunc_prolog(CType *func_type);
+ST_FUNC void gfunc_epilog(void);
+ST_FUNC int gjmp(int t);
+ST_FUNC void gjmp_addr(int a);
+ST_FUNC int gtst(int inv, int t);
+ST_FUNC void gen_opi(int op);
+ST_FUNC void gen_opf(int op);
+ST_FUNC void gen_cvt_ftoi(int t);
+ST_FUNC void gen_cvt_ftof(int t);
+ST_FUNC void ggoto(void);
+#ifndef TCC_TARGET_C67
+ST_FUNC void o(unsigned int c);
+#endif
+#ifndef TCC_TARGET_ARM
+ST_FUNC void gen_cvt_itof(int t);
+#endif
+
+/* ------------ i386-gen.c ------------ */
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC void g(int c);
+ST_FUNC int oad(int c, int s);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
+ST_FUNC void gen_addr32(int r, Sym *sym, int c);
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void gen_bounded_ptr_add(void);
+ST_FUNC void gen_bounded_ptr_deref(void);
+#endif
+
+/* ------------ x86_64-gen.c ------------ */
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
+#endif
+
+/* ------------ arm-gen.c ------------ */
+#ifdef TCC_TARGET_ARM
+ST_FUNC unsigned long encbranch(int pos,int addr,int fail);
+ST_FUNC void gen_cvt_itof1(int t);
+#endif
+
+/* ------------ c67-gen.c ------------ */
+#ifdef TCC_TARGET_C67
+#endif
+
+/* ------------ tcccoff.c ------------ */
+
+#ifdef TCC_TARGET_COFF
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
+#endif
+
+/* ------------ tccasm.c ------------ */
+ST_FUNC void asm_instr(void);
+ST_FUNC void asm_global_instr(void);
+
+#ifdef CONFIG_TCC_ASM
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
+ST_FUNC int asm_int_expr(TCCState *s1);
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
+/* ------------ i386-asm.c ------------ */
+ST_FUNC void gen_expr32(ExprValue *pe);
+ST_FUNC void asm_opcode(TCCState *s1, int opcode);
+ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
+#endif
+/* ------------ tccpe.c -------------- */
+#ifdef TCC_TARGET_PE
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
+ST_FUNC int pe_add_dll(struct TCCState *s, const char *libraryname);
+ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
+ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv));
+/* tiny_impdef.c */
+ST_FUNC char *get_export_names(FILE *fp);
+#endif
+
+/* ------------ tccrun.c ----------------- */
+#if !defined CONFIG_TCC_STATIC && !defined _WIN32
+ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
+#endif
+
+/********************************************************/
+/* include the target specific definitions */
+
+#define TARGET_DEFS_ONLY
+#ifdef TCC_TARGET_I386
+#include "i386-gen.c"
+#endif
+#ifdef TCC_TARGET_X86_64
+#include "x86_64-gen.c"
+#endif
+#ifdef TCC_TARGET_ARM
+#include "arm-gen.c"
+#endif
+#ifdef TCC_TARGET_C67
+#include "c67-gen.c"
+#endif
+#undef TARGET_DEFS_ONLY
+
+ST_DATA const int reg_classes[NB_REGS];
+
+/********************************************************/
+#undef ST_DATA
+#ifndef NOTALLINONE
+#define ST_DATA static
+#else
+#define ST_DATA
+#endif
+/********************************************************/
+#endif /* _TCC_H */
diff --git a/tccasm.c b/tccasm.c
index 56bf6cd..28161be 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -18,7 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-static int asm_get_local_label_name(TCCState *s1, unsigned int n)
+#include "tcc.h"
+
+ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
{
char buf[64];
TokenSym *ts;
@@ -28,7 +30,7 @@ static int asm_get_local_label_name(TCCState *s1, unsigned int n)
return ts->tok;
}
-static void asm_expr(TCCState *s1, ExprValue *pe);
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
/* We do not use the C expression parser to handle symbols. Maybe the
C expression parser could be tweaked to do so. */
@@ -238,12 +240,12 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
}
}
-static void asm_expr(TCCState *s1, ExprValue *pe)
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
{
asm_expr_sum(s1, pe);
}
-static int asm_int_expr(TCCState *s1)
+ST_FUNC int asm_int_expr(TCCState *s1)
{
ExprValue e;
asm_expr(s1, &e);
@@ -699,7 +701,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
}
/* Assemble the current file */
-static int tcc_assemble(TCCState *s1, int do_preprocess)
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
{
Sym *define_start;
int ret;
@@ -765,7 +767,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len)
/* 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,
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
const char *name, const char **pp)
{
int index;
@@ -916,7 +918,7 @@ static void parse_asm_str(CString *astr)
}
/* parse the GCC asm() instruction */
-static void asm_instr(void)
+ST_FUNC void asm_instr(void)
{
CString astr, astr1;
ASMOperand operands[MAX_ASM_OPERANDS];
@@ -1017,7 +1019,7 @@ static void asm_instr(void)
cstr_free(&astr1);
}
-static void asm_global_instr(void)
+ST_FUNC void asm_global_instr(void)
{
CString astr;
diff --git a/tcccoff.c b/tcccoff.c
index 0dcbe50..0ab9ace 100644
--- a/tcccoff.c
+++ b/tcccoff.c
@@ -18,6 +18,8 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
+#include "tcc.h"
#include "coff.h"
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
@@ -73,7 +75,7 @@ typedef struct {
unsigned short dummy4;
} AUXEF;
-int tcc_output_coff(TCCState *s1, FILE *f)
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
{
Section *tcc_sect;
SCNHDR *coff_sec;
diff --git a/tccelf.c b/tccelf.c
index 1b4a804..25d80d7 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "tcc.h"
+
#ifdef TCC_TARGET_X86_64
#define ElfW_Rel ElfW(Rela)
#define SHT_RELX SHT_RELA
@@ -33,7 +35,7 @@
/* XXX: DLL with PLT would only work with x86-64 for now */
//#define TCC_OUTPUT_DLL_WITH_PLT
-static int put_elf_str(Section *s, const char *sym)
+ST_FUNC int put_elf_str(Section *s, const char *sym)
{
int offset, len;
char *ptr;
@@ -95,7 +97,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets)
}
/* return the symbol number */
-static int put_elf_sym(Section *s,
+ST_FUNC int put_elf_sym(Section *s,
unsigned long value, unsigned long size,
int info, int other, int shndx, const char *name)
{
@@ -145,7 +147,7 @@ static int put_elf_sym(Section *s,
/* find global ELF symbol 'name' and return its index. Return 0 if not
found. */
-static int find_elf_sym(Section *s, const char *name)
+ST_FUNC int find_elf_sym(Section *s, const char *name)
{
ElfW(Sym) *sym;
Section *hs;
@@ -185,20 +187,20 @@ static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
}
/* return elf symbol value */
-void *tcc_get_symbol(TCCState *s, const char *name)
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
{
return get_elf_sym_addr(s, name, 0);
}
/* return elf symbol value or error */
-void *tcc_get_symbol_err(TCCState *s, const char *name)
+ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name)
{
return get_elf_sym_addr(s, name, 1);
}
/* 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, uplong value, unsigned long size,
+ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size,
int info, int other, int sh_num, const char *name)
{
ElfW(Sym) *esym;
@@ -272,7 +274,7 @@ static int add_elf_sym(Section *s, uplong value, unsigned long size,
}
/* put relocation */
-static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
int type, int symbol)
{
char buf[256];
@@ -301,15 +303,7 @@ static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
/* put stab debug information */
-typedef struct {
- unsigned int n_strx; /* index into string table of name */
- unsigned char n_type; /* type of symbol */
- unsigned char n_other; /* misc info (usually empty) */
- unsigned short n_desc; /* description field */
- unsigned int n_value; /* value of symbol */
-} Stab_Sym;
-
-static void put_stabs(const char *str, int type, int other, int desc,
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
unsigned long value)
{
Stab_Sym *sym;
@@ -326,7 +320,7 @@ static void put_stabs(const char *str, int type, int other, int desc,
sym->n_value = value;
}
-static void put_stabs_r(const char *str, int type, int other, int desc,
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
unsigned long value, Section *sec, int sym_index)
{
put_stabs(str, type, other, desc, value);
@@ -335,12 +329,12 @@ static void put_stabs_r(const char *str, int type, int other, int desc,
R_DATA_32, sym_index);
}
-static void put_stabn(int type, int other, int desc, int value)
+ST_FUNC void put_stabn(int type, int other, int desc, int value)
{
put_stabs(NULL, type, other, desc, value);
}
-static void put_stabd(int type, int other, int desc)
+ST_FUNC void put_stabd(int type, int other, int desc)
{
put_stabs(NULL, type, other, desc, 0);
}
@@ -410,7 +404,7 @@ static void sort_syms(TCCState *s1, Section *s)
}
/* relocate common symbols in the .bss section */
-static void relocate_common_syms(void)
+ST_FUNC void relocate_common_syms(void)
{
ElfW(Sym) *sym, *sym_end;
unsigned long offset, align;
@@ -434,7 +428,7 @@ static void relocate_common_syms(void)
/* 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)
+ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
{
ElfW(Sym) *sym, *esym, *sym_end;
int sym_bind, sh_num, sym_index;
@@ -513,7 +507,7 @@ static unsigned long add_got_table(TCCState *s1, unsigned long val)
#endif
/* relocate a given section (CPU dependent) */
-static void relocate_section(TCCState *s1, Section *s)
+ST_FUNC void relocate_section(TCCState *s1, Section *s)
{
Section *sr;
ElfW_Rel *rel, *rel_end, *qrel;
@@ -1012,7 +1006,7 @@ static void put_got_entry(TCCState *s1,
}
/* build GOT and PLT entries */
-static void build_got_entries(TCCState *s1)
+ST_FUNC void build_got_entries(TCCState *s1)
{
Section *s, *symtab;
ElfW_Rel *rel, *rel_end;
@@ -1120,7 +1114,7 @@ static void build_got_entries(TCCState *s1)
}
}
-static Section *new_symtab(TCCState *s1,
+ST_FUNC Section *new_symtab(TCCState *s1,
const char *symtab_name, int sh_type, int sh_flags,
const char *strtab_name,
const char *hash_name, int hash_sh_flags)
@@ -1186,7 +1180,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
s->sh_num, sym_end);
}
-static void tcc_add_bcheck(TCCState *s1)
+ST_FUNC void tcc_add_bcheck(TCCState *s1)
{
#ifdef CONFIG_TCC_BCHECK
unsigned long *ptr;
@@ -1227,7 +1221,7 @@ static void tcc_add_bcheck(TCCState *s1)
}
/* add tcc runtime libraries */
-static void tcc_add_runtime(TCCState *s1)
+ST_FUNC void tcc_add_runtime(TCCState *s1)
{
tcc_add_bcheck(s1);
@@ -1252,7 +1246,7 @@ static void tcc_add_runtime(TCCState *s1)
/* 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)
+ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
{
char buf[1024];
int i;
@@ -1371,7 +1365,7 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
/* output an ELF file */
/* XXX: suppress unneeded sections */
-int elf_output_file(TCCState *s1, const char *filename)
+static int elf_output_file(TCCState *s1, const char *filename)
{
ElfW(Ehdr) ehdr;
FILE *f;
@@ -2110,7 +2104,7 @@ int elf_output_file(TCCState *s1, const char *filename)
return ret;
}
-int tcc_output_file(TCCState *s, const char *filename)
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
{
int ret;
#ifdef TCC_TARGET_PE
@@ -2143,7 +2137,7 @@ typedef struct SectionMergeInfo {
/* load an object file and merge it with current files */
/* XXX: handle correctly stab (debug) info */
-static int tcc_load_object_file(TCCState *s1,
+ST_FUNC int tcc_load_object_file(TCCState *s1,
int fd, unsigned long file_offset)
{
ElfW(Ehdr) ehdr;
@@ -2412,8 +2406,6 @@ static int tcc_load_object_file(TCCState *s1,
return ret;
}
-#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
-
typedef struct ArchiveHeader {
char ar_name[16]; /* name of this member */
char ar_date[12]; /* file mtime */
@@ -2474,7 +2466,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
}
/* load a '.a' file */
-static int tcc_load_archive(TCCState *s1, int fd)
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
{
ArchiveHeader hdr;
char ar_size[11];
@@ -2529,7 +2521,7 @@ static int tcc_load_archive(TCCState *s1, int fd)
/* 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)
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
{
ElfW(Ehdr) ehdr;
ElfW(Shdr) *shdr, *sh, *sh1;
@@ -2802,7 +2794,7 @@ static int ld_add_file_list(TCCState *s1, int as_needed)
/* interpret a subset of GNU ldscripts to handle the dummy libc.so
files */
-static int tcc_load_ldscript(TCCState *s1)
+ST_FUNC int tcc_load_ldscript(TCCState *s1)
{
char cmd[64];
char filename[1024];
diff --git a/tccgen.c b/tccgen.c
index 9866c55..af1abc1 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -18,7 +18,244 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-void swap(int *p, int *q)
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+/* loc : local variable index
+ ind : output code index
+ rsym: return symbol
+ anon_sym: anonymous symbol index
+*/
+ST_DATA int rsym, anon_sym, ind, loc;
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section, *strtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *define_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *local_label_stack;
+
+ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
+
+ST_DATA int const_wanted; /* true if constant wanted */
+ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
+ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
+ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA char *funcname;
+
+ST_DATA CType char_pointer_type, func_old_type, int_type;
+
+/* ------------------------------------------------------------------------- */
+static void gen_cast(CType *type);
+static inline CType *pointed_type(CType *type);
+static int is_compatible_types(CType *type1, CType *type2);
+static int parse_btype(CType *type, AttributeDef *ad);
+static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
+static void parse_expr_type(CType *type);
+static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
+static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
+static void expr_eq(void);
+static void unary_type(CType *type);
+static int is_compatible_parameter_types(CType *type1, CType *type2);
+static void expr_type(CType *type);
+
+ST_INLN int is_float(int t)
+{
+ int bt;
+ bt = t & VT_BTYPE;
+ return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
+}
+
+ST_FUNC void test_lvalue(void)
+{
+ if (!(vtop->r & VT_LVAL))
+ expect("lvalue");
+}
+
+/* ------------------------------------------------------------------------- */
+/* symbol allocator */
+static Sym *__sym_malloc(void)
+{
+ Sym *sym_pool, *sym, *last_sym;
+ int i;
+
+ sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
+ dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
+
+ last_sym = sym_free_first;
+ sym = sym_pool;
+ for(i = 0; i < SYM_POOL_NB; i++) {
+ sym->next = last_sym;
+ last_sym = sym;
+ sym++;
+ }
+ sym_free_first = last_sym;
+ return last_sym;
+}
+
+static inline Sym *sym_malloc(void)
+{
+ Sym *sym;
+ sym = sym_free_first;
+ if (!sym)
+ sym = __sym_malloc();
+ sym_free_first = sym->next;
+ return sym;
+}
+
+ST_INLN void sym_free(Sym *sym)
+{
+ sym->next = sym_free_first;
+ sym_free_first = sym;
+}
+
+/* push, without hashing */
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
+{
+ Sym *s;
+ s = sym_malloc();
+ s->v = v;
+ s->type.t = t;
+ s->type.ref = NULL;
+#ifdef _WIN64
+ s->d = NULL;
+#endif
+ s->c = c;
+ s->next = NULL;
+ /* add in stack */
+ s->prev = *ps;
+ *ps = s;
+ return s;
+}
+
+/* find a symbol and return its associated structure. 's' is the top
+ of the symbol stack */
+ST_FUNC Sym *sym_find2(Sym *s, int v)
+{
+ while (s) {
+ if (s->v == v)
+ return s;
+ s = s->prev;
+ }
+ return NULL;
+}
+
+/* structure lookup */
+ST_INLN Sym *struct_find(int v)
+{
+ v -= TOK_IDENT;
+ if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+ return NULL;
+ return table_ident[v]->sym_struct;
+}
+
+/* find an identifier */
+ST_INLN Sym *sym_find(int v)
+{
+ v -= TOK_IDENT;
+ if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+ return NULL;
+ return table_ident[v]->sym_identifier;
+}
+
+/* push a given symbol on the symbol stack */
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
+{
+ Sym *s, **ps;
+ TokenSym *ts;
+
+ if (local_stack)
+ ps = &local_stack;
+ else
+ ps = &global_stack;
+ s = sym_push2(ps, v, type->t, c);
+ s->type.ref = type->ref;
+ s->r = r;
+ /* don't record fields or anonymous symbols */
+ /* XXX: simplify */
+ if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+ /* record symbol in token array */
+ ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+ if (v & SYM_STRUCT)
+ ps = &ts->sym_struct;
+ else
+ ps = &ts->sym_identifier;
+ s->prev_tok = *ps;
+ *ps = s;
+ }
+ return s;
+}
+
+/* push a global identifier */
+ST_FUNC Sym *global_identifier_push(int v, int t, int c)
+{
+ Sym *s, **ps;
+ s = sym_push2(&global_stack, v, t, c);
+ /* don't record anonymous symbol */
+ if (v < SYM_FIRST_ANOM) {
+ ps = &table_ident[v - TOK_IDENT]->sym_identifier;
+ /* modify the top most local identifier, so that
+ sym_identifier will point to 's' when popped */
+ while (*ps != NULL)
+ ps = &(*ps)->prev_tok;
+ s->prev_tok = NULL;
+ *ps = s;
+ }
+ return s;
+}
+
+/* pop symbols until top reaches 'b' */
+ST_FUNC void sym_pop(Sym **ptop, Sym *b)
+{
+ Sym *s, *ss, **ps;
+ TokenSym *ts;
+ int v;
+
+ s = *ptop;
+ while(s != b) {
+ ss = s->prev;
+ v = s->v;
+ /* remove symbol in token array */
+ /* XXX: simplify */
+ if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+ ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+ if (v & SYM_STRUCT)
+ ps = &ts->sym_struct;
+ else
+ ps = &ts->sym_identifier;
+ *ps = s->prev_tok;
+ }
+ sym_free(s);
+ s = ss;
+ }
+ *ptop = b;
+}
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC void swap(int *p, int *q)
{
int t;
t = *p;
@@ -26,7 +263,7 @@ void swap(int *p, int *q)
*q = t;
}
-void vsetc(CType *type, int r, CValue *vc)
+static void vsetc(CType *type, int r, CValue *vc)
{
int v;
@@ -48,7 +285,7 @@ void vsetc(CType *type, int r, CValue *vc)
}
/* push integer constant */
-void vpushi(int v)
+ST_FUNC void vpushi(int v)
{
CValue cval;
cval.i = v;
@@ -56,7 +293,7 @@ void vpushi(int v)
}
/* push long long constant */
-void vpushll(long long v)
+static void vpushll(long long v)
{
CValue cval;
CType ctype;
@@ -67,8 +304,7 @@ void vpushll(long long v)
}
/* Return a static symbol pointing to a section */
-static Sym *get_sym_ref(CType *type, Section *sec,
- unsigned long offset, unsigned long size)
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
{
int v;
Sym *sym;
@@ -92,7 +328,7 @@ static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned
}
/* define a new external reference to a symbol 'v' of type 'u' */
-static Sym *external_global_sym(int v, CType *type, int r)
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
{
Sym *s;
@@ -139,7 +375,7 @@ static void vpush_global_sym(CType *type, int v)
vtop->sym = sym;
}
-void vset(CType *type, int r, int v)
+ST_FUNC void vset(CType *type, int r, int v)
{
CValue cval;
@@ -147,7 +383,7 @@ void vset(CType *type, int r, int v)
vsetc(type, r, &cval);
}
-void vseti(int r, int v)
+static void vseti(int r, int v)
{
CType type;
type.t = VT_INT;
@@ -155,7 +391,7 @@ void vseti(int r, int v)
vset(&type, r, v);
}
-void vswap(void)
+ST_FUNC void vswap(void)
{
SValue tmp;
@@ -164,7 +400,7 @@ void vswap(void)
vtop[-1] = tmp;
}
-void vpushv(SValue *v)
+static void vpushv(SValue *v)
{
if (vtop >= vstack + (VSTACK_SIZE - 1))
error("memory full");
@@ -172,13 +408,13 @@ void vpushv(SValue *v)
*vtop = *v;
}
-void vdup(void)
+static void vdup(void)
{
vpushv(vtop);
}
/* save r to the memory stack, and mark it as being free */
-void save_reg(int r)
+ST_FUNC void save_reg(int r)
{
int l, saved, size, align;
SValue *p, sv;
@@ -240,9 +476,10 @@ void save_reg(int r)
}
}
+#ifdef TCC_TARGET_ARM
/* 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)
+ST_FUNC int get_reg_ex(int rc, int rc2)
{
int r;
SValue *p;
@@ -262,9 +499,10 @@ int get_reg_ex(int rc, int rc2)
}
return get_reg(rc);
}
+#endif
/* find a free register of class 'rc'. If none, save one register */
-int get_reg(int rc)
+ST_FUNC int get_reg(int rc)
{
int r;
SValue *p;
@@ -302,7 +540,7 @@ int get_reg(int rc)
}
/* save registers up to (vtop - n) stack entry */
-void save_regs(int n)
+ST_FUNC void save_regs(int n)
{
int r;
SValue *p, *p1;
@@ -317,7 +555,7 @@ void save_regs(int n)
/* move register 's' to 'r', and flush previous value of r to memory
if needed */
-void move_reg(int r, int s)
+static void move_reg(int r, int s)
{
SValue sv;
@@ -331,7 +569,7 @@ void move_reg(int r, int s)
}
/* get address of vtop (vtop MUST BE an lvalue) */
-void gaddrof(void)
+static void gaddrof(void)
{
vtop->r &= ~VT_LVAL;
/* tricky: if saved lvalue, then we can go back to lvalue */
@@ -341,7 +579,7 @@ void gaddrof(void)
#ifdef CONFIG_TCC_BCHECK
/* generate lvalue bound code */
-void gbound(void)
+static void gbound(void)
{
int lval_type;
CType type1;
@@ -370,7 +608,7 @@ void gbound(void)
/* 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)
+ST_FUNC int gv(int rc)
{
int r, rc2, bit_pos, bit_size, size, align, i;
@@ -537,7 +775,7 @@ int gv(int rc)
}
/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
-void gv2(int rc1, int rc2)
+ST_FUNC void gv2(int rc1, int rc2)
{
int v;
@@ -569,7 +807,7 @@ void gv2(int rc1, int rc2)
}
/* wrapper around RC_FRET to return a register by type */
-int rc_fret(int t)
+static int rc_fret(int t)
{
#ifdef TCC_TARGET_X86_64
if (t == VT_LDOUBLE) {
@@ -580,7 +818,7 @@ int rc_fret(int t)
}
/* wrapper around REG_FRET to return a register by type */
-int reg_fret(int t)
+static int reg_fret(int t)
{
#ifdef TCC_TARGET_X86_64
if (t == VT_LDOUBLE) {
@@ -591,7 +829,7 @@ int reg_fret(int t)
}
/* expand long long on stack in two int registers */
-void lexpand(void)
+static void lexpand(void)
{
int u;
@@ -607,7 +845,7 @@ void lexpand(void)
#ifdef TCC_TARGET_ARM
/* expand long long on stack */
-void lexpand_nr(void)
+ST_FUNC void lexpand_nr(void)
{
int u,v;
@@ -634,7 +872,7 @@ void lexpand_nr(void)
#endif
/* build a long long from two ints */
-void lbuild(int t)
+static void lbuild(int t)
{
gv2(RC_INT, RC_INT);
vtop[-1].r2 = vtop[0].r;
@@ -645,7 +883,7 @@ void lbuild(int t)
/* rotate n first stack elements to the bottom
I1 ... In -> I2 ... In I1 [top is right]
*/
-void vrotb(int n)
+static void vrotb(int n)
{
int i;
SValue tmp;
@@ -659,7 +897,7 @@ void vrotb(int n)
/* rotate n first stack elements to the top
I1 ... In -> In I1 ... I(n-1) [top is right]
*/
-void vrott(int n)
+static void vrott(int n)
{
int i;
SValue tmp;
@@ -687,7 +925,7 @@ void vnrott(int n)
#endif
/* pop stack value */
-void vpop(void)
+ST_FUNC void vpop(void)
{
int v;
v = vtop->r & VT_VALMASK;
@@ -706,7 +944,7 @@ void vpop(void)
/* convert stack entry to register and duplicate its value in another
register */
-void gv_dup(void)
+static void gv_dup(void)
{
int rc, t, r, r1;
SValue sv;
@@ -753,7 +991,7 @@ void gv_dup(void)
#ifndef TCC_TARGET_X86_64
/* generate CPU independent (unsigned) long long operations */
-void gen_opl(int op)
+static void gen_opl(int op)
{
int t, a, b, op1, c, i;
int func;
@@ -990,7 +1228,7 @@ void gen_opl(int op)
/* handle integer constant optimizations and various machine
independent opt */
-void gen_opic(int op)
+static void gen_opic(int op)
{
int c1, c2, t1, t2, n;
SValue *v1, *v2;
@@ -1130,7 +1368,7 @@ void gen_opic(int op)
}
/* generate a floating point operation with constant propagation */
-void gen_opif(int op)
+static void gen_opif(int op)
{
int c1, c2;
SValue *v1, *v2;
@@ -1262,7 +1500,7 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
}
/* generic gen_op: handles types problems */
-void gen_op(int op)
+ST_FUNC void gen_op(int op)
{
int u, t1, t2, bt1, bt2, t;
CType type1;
@@ -1411,7 +1649,7 @@ void gen_op(int op)
#ifndef TCC_TARGET_ARM
/* generic itof for unsigned long long case */
-void gen_cvt_itof1(int t)
+static void gen_cvt_itof1(int t)
{
if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_LLONG | VT_UNSIGNED)) {
@@ -1435,7 +1673,7 @@ void gen_cvt_itof1(int t)
#endif
/* generic ftoi for unsigned long long case */
-void gen_cvt_ftoi1(int t)
+static void gen_cvt_ftoi1(int t)
{
int st;
@@ -1461,7 +1699,7 @@ void gen_cvt_ftoi1(int t)
}
/* force char or short cast */
-void force_charshort_cast(int t)
+static void force_charshort_cast(int t)
{
int bits, dbt;
dbt = t & VT_BTYPE;
@@ -1672,7 +1910,7 @@ static void gen_cast(CType *type)
}
/* return type size. Put alignment at 'a' */
-static int type_size(CType *type, int *a)
+ST_FUNC int type_size(CType *type, int *a)
{
Sym *s;
int bt;
@@ -1738,7 +1976,7 @@ static inline CType *pointed_type(CType *type)
}
/* modify type so that its it is a pointer to type. */
-static void mk_pointer(CType *type)
+ST_FUNC void mk_pointer(CType *type)
{
Sym *s;
s = sym_push(SYM_FIELD, type, 0, -1);
@@ -1829,7 +2067,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2)
printed in the type */
/* XXX: union */
/* XXX: add array and function pointers */
-void type_to_str(char *buf, int buf_size,
+static void type_to_str(char *buf, int buf_size,
CType *type, const char *varstr)
{
int bt, v, t;
@@ -2000,7 +2238,7 @@ static void gen_assign_cast(CType *dt)
}
/* store vtop in lvalue pushed on stack */
-void vstore(void)
+ST_FUNC void vstore(void)
{
int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
@@ -2161,7 +2399,7 @@ void vstore(void)
}
/* post defines POST/PRE add. c is the token ++ or -- */
-void inc(int post, int c)
+ST_FUNC void inc(int post, int c)
{
test_lvalue();
vdup(); /* save lvalue */
@@ -2879,7 +3117,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
}
/* compute the lvalue VT_LVAL_xxx needed to match type t. */
-static int lvalue_type(int t)
+ST_FUNC int lvalue_type(int t)
{
int bt, r;
r = VT_LVAL;
@@ -2896,7 +3134,7 @@ static int lvalue_type(int t)
}
/* indirection with full error checking and bound check */
-static void indir(void)
+ST_FUNC void indir(void)
{
if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
@@ -2976,7 +3214,7 @@ static void vpush_tokc(int t)
vsetc(&type, VT_CONST, &tokc);
}
-static void unary(void)
+ST_FUNC void unary(void)
{
int n, t, align, size, r;
CType type;
@@ -3444,7 +3682,7 @@ static void uneq(void)
}
}
-static void expr_prod(void)
+ST_FUNC void expr_prod(void)
{
int t;
@@ -3457,7 +3695,7 @@ static void expr_prod(void)
}
}
-static void expr_sum(void)
+ST_FUNC void expr_sum(void)
{
int t;
@@ -3745,7 +3983,7 @@ static void expr_eq(void)
}
}
-static void gexpr(void)
+ST_FUNC void gexpr(void)
{
while (1) {
expr_eq();
@@ -3794,7 +4032,7 @@ static void expr_const1(void)
}
/* parse an integer constant and return its value. */
-static int expr_const(void)
+ST_FUNC int expr_const(void)
{
int c;
expr_const1();
@@ -4848,7 +5086,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
no_alloc: ;
}
-void put_func_debug(Sym *sym)
+static void put_func_debug(Sym *sym)
{
char buf[512];
@@ -4951,7 +5189,7 @@ static void gen_function(Sym *sym)
nocode_wanted = saved_nocode_wanted;
}
-static void gen_inline_functions(void)
+ST_FUNC void gen_inline_functions(void)
{
Sym *sym;
int *str, inline_generated, i;
@@ -4994,7 +5232,7 @@ static void gen_inline_functions(void)
}
/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
-static void decl(int l)
+ST_FUNC void decl(int l)
{
int v, has_init, r;
CType type, btype;
diff --git a/tccpe.c b/tccpe.c
index d603a5e..1b2724d 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -18,11 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifdef TCC_TARGET_PE
-
-#define ST_FN static
-#define ST_DATA static
-#define PUB_FN
+#include "tcc.h"
#ifndef _WIN32
#define stricmp strcasecmp
@@ -300,7 +296,7 @@ enum {
sec_last
};
-ST_DATA const DWORD pe_sec_flags[] = {
+static const DWORD pe_sec_flags[] = {
0x60000020, /* ".text" , */
0xC0000040, /* ".data" , */
0xC0000080, /* ".bss" , */
@@ -366,7 +362,7 @@ struct pe_info {
/* --------------------------------------------*/
-ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)
+static const char* get_alt_symbol(char *buffer, const char *symbol)
{
const char *p;
p = strrchr(symbol, '@');
@@ -384,7 +380,7 @@ ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)
return buffer;
}
-ST_FN int pe_find_import(TCCState * s1, const char *symbol)
+static int pe_find_import(TCCState * s1, const char *symbol)
{
char buffer[200];
const char *s;
@@ -399,7 +395,7 @@ ST_FN int pe_find_import(TCCState * s1, const char *symbol)
/*----------------------------------------------------------------------------*/
-ST_FN int dynarray_assoc(void **pp, int n, int key)
+static int dynarray_assoc(void **pp, int n, int key)
{
int i;
for (i = 0; i < n; ++i, ++pp)
@@ -415,35 +411,35 @@ ST_FN DWORD umin(DWORD a, DWORD b)
}
#endif
-ST_FN DWORD umax(DWORD a, DWORD b)
+static DWORD umax(DWORD a, DWORD b)
{
return a < b ? b : a;
}
-ST_FN DWORD pe_file_align(struct pe_info *pe, DWORD n)
+static DWORD pe_file_align(struct pe_info *pe, DWORD n)
{
return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
}
-ST_FN DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
+static DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
{
return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
}
-ST_FN void pe_align_section(Section *s, int a)
+static void pe_align_section(Section *s, int a)
{
int i = s->data_offset & (a-1);
if (i)
section_ptr_add(s, a - i);
}
-ST_FN void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
+static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
{
hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;
hdr->opthdr.DataDirectory[dir].Size = size;
}
-ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
+static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
{
if (psum) {
DWORD sum = *psum;
@@ -458,7 +454,7 @@ ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
return len == fwrite(data, 1, len, fp) ? 0 : -1;
}
-ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
+static void pe_fpad(FILE *fp, DWORD new_pos)
{
DWORD pos = ftell(fp);
while (++pos <= new_pos)
@@ -466,7 +462,7 @@ ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
}
/*----------------------------------------------------------------------------*/
-ST_FN int pe_write(struct pe_info *pe)
+static int pe_write(struct pe_info *pe)
{
static const struct pe_header pe_template = {
{
@@ -745,7 +741,7 @@ ST_FN int pe_write(struct pe_info *pe)
#endif
/*----------------------------------------------------------------------------*/
-ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
+static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
{
int i;
int dll_index;
@@ -777,7 +773,7 @@ found_dll:
}
/*----------------------------------------------------------------------------*/
-ST_FN void pe_build_imports(struct pe_info *pe)
+static void pe_build_imports(struct pe_info *pe)
{
int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;
DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;
@@ -860,14 +856,14 @@ struct pe_sort_sym
const char *name;
};
-ST_FN int sym_cmp(const void *va, const void *vb)
+static int sym_cmp(const void *va, const void *vb)
{
const char *ca = (*(struct pe_sort_sym**)va)->name;
const char *cb = (*(struct pe_sort_sym**)vb)->name;
return strcmp(ca, cb);
}
-ST_FN void pe_build_exports(struct pe_info *pe)
+static void pe_build_exports(struct pe_info *pe)
{
ElfW(Sym) *sym;
int sym_index, sym_end;
@@ -967,7 +963,7 @@ ST_FN void pe_build_exports(struct pe_info *pe)
}
/* ------------------------------------------------------------- */
-ST_FN void pe_build_reloc (struct pe_info *pe)
+static void pe_build_reloc (struct pe_info *pe)
{
DWORD offset, block_ptr, addr;
int count, i;
@@ -1023,7 +1019,7 @@ ST_FN void pe_build_reloc (struct pe_info *pe)
}
/* ------------------------------------------------------------- */
-ST_FN int pe_section_class(Section *s)
+static int pe_section_class(Section *s)
{
int type, flags;
const char *name;
@@ -1055,7 +1051,7 @@ ST_FN int pe_section_class(Section *s)
return -1;
}
-ST_FN int pe_assign_addresses (struct pe_info *pe)
+static int pe_assign_addresses (struct pe_info *pe)
{
int i, k, o, c;
DWORD addr;
@@ -1153,7 +1149,7 @@ ST_FN int pe_assign_addresses (struct pe_info *pe)
}
/* ------------------------------------------------------------- */
-ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s)
+static void pe_relocate_rva (struct pe_info *pe, Section *s)
{
Section *sr = s->reloc;
ElfW_Rel *rel, *rel_end;
@@ -1173,6 +1169,7 @@ ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s)
}
/*----------------------------------------------------------------------------*/
+
static int pe_isafunc(int sym_index)
{
Section *sr = text_section->reloc;
@@ -1188,7 +1185,7 @@ static int pe_isafunc(int sym_index)
}
/*----------------------------------------------------------------------------*/
-ST_FN int pe_check_symbols(struct pe_info *pe)
+static int pe_check_symbols(struct pe_info *pe)
{
ElfW(Sym) *sym;
int sym_index, sym_end;
@@ -1282,7 +1279,7 @@ ST_FN int pe_check_symbols(struct pe_info *pe)
/*----------------------------------------------------------------------------*/
#ifdef PE_PRINT_SECTIONS
-ST_FN void pe_print_section(FILE * f, Section * s)
+static void pe_print_section(FILE * f, Section * s)
{
/* just if you'r curious */
BYTE *p, *e, b;
@@ -1404,7 +1401,7 @@ ST_FN void pe_print_section(FILE * f, Section * s)
fprintf(f, "\n\n");
}
-ST_FN void pe_print_sections(TCCState *s1, const char *fname)
+static void pe_print_sections(TCCState *s1, const char *fname)
{
Section *s;
FILE *f;
@@ -1420,34 +1417,8 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname)
#endif
/* ------------------------------------------------------------- */
-/* helper function for load/store to insert one more indirection */
-int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))
-{
- int t;
- if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
- return 0;
- t = sv->sym->type.t;
- if (0 == (t & VT_IMPORT))
- return 0;
-
- sv->sym->type.t = t & ~VT_IMPORT;
- //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL));
-
- *++vtop = *sv;
- vtop->type.t &= ~(VT_ARRAY|VT_IMPORT);
- mk_pointer(&vtop->type);
- indir();
- fn(r, vtop);
- --vtop;
-
- sv->sym->type.t = t;
- return 1;
-}
-
-/* ------------------------------------------------------------- */
-
-ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
+static int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
{
fseek(fp, offset, 0);
return len == fread(buffer, 1, len, fp);
@@ -1458,7 +1429,7 @@ ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
* as generated by 'windres.exe -O coff ...'.
*/
-ST_FN int pe_load_res(TCCState *s1, FILE *fp)
+static int pe_load_res(TCCState *s1, FILE *fp)
{
struct pe_rsrc_header hdr;
Section *rsrc_section;
@@ -1498,14 +1469,14 @@ quit:
}
/* ------------------------------------------------------------- */
-ST_FN char *trimfront(char *p)
+static char *trimfront(char *p)
{
while (*p && (unsigned char)*p <= ' ')
++p;
return p;
}
-ST_FN char *trimback(char *a, char *e)
+static char *trimback(char *a, char *e)
{
while (e > a && (unsigned char)e[-1] <= ' ')
--e;
@@ -1513,7 +1484,7 @@ ST_FN char *trimback(char *a, char *e)
return a;
}
-ST_FN char *get_line(char *line, int size, FILE *fp)
+static char *get_line(char *line, int size, FILE *fp)
{
if (NULL == fgets(line, size, fp))
return NULL;
@@ -1522,7 +1493,7 @@ ST_FN char *get_line(char *line, int size, FILE *fp)
}
/* ------------------------------------------------------------- */
-ST_FN int pe_load_def(TCCState *s1, FILE *fp)
+static int pe_load_def(TCCState *s1, FILE *fp)
{
DLLReference *dllref;
int state = 0, ret = -1;
@@ -1571,7 +1542,7 @@ quit:
#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
#include "win32/tools/tiny_impdef.c"
-ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
+static int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
{
int i = 0;
char *p, *q;
@@ -1594,7 +1565,7 @@ ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
}
/* ------------------------------------------------------------- */
-PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd)
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
{
FILE *fp = fdopen(dup(fd), "rb");
int ret = -1;
@@ -1611,7 +1582,7 @@ PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd)
return ret;
}
-int pe_add_dll(struct TCCState *s, const char *libname)
+ST_FUNC int pe_add_dll(struct TCCState *s, const char *libname)
{
static const char *pat[] = {
"%s.def", "lib%s.def", "%s.dll", "lib%s.dll", NULL
@@ -1627,13 +1598,39 @@ int pe_add_dll(struct TCCState *s, const char *libname)
}
/* ------------------------------------------------------------- */
+/* helper function for load/store to insert one more indirection */
+
+ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))
+{
+ int t;
+ if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
+ return 0;
+ t = sv->sym->type.t;
+ if (0 == (t & VT_IMPORT))
+ return 0;
+
+ sv->sym->type.t = t & ~VT_IMPORT;
+ //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL));
+
+ *++vtop = *sv;
+ vtop->type.t &= ~(VT_ARRAY|VT_IMPORT);
+ mk_pointer(&vtop->type);
+ indir();
+ fn(r, vtop);
+ --vtop;
+
+ sv->sym->type.t = t;
+ return 1;
+}
+
+/* ------------------------------------------------------------- */
#ifdef TCC_TARGET_X86_64
#define PE_STDSYM(n,s) n
#else
#define PE_STDSYM(n,s) "_" n s
#endif
-ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
+static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
{
const char *start_symbol;
unsigned long addr = 0;
@@ -1690,7 +1687,7 @@ ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
pe->start_addr = addr;
}
-PUB_FN int pe_output_file(TCCState * s1, const char *filename)
+ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
{
int ret;
struct pe_info pe;
@@ -1780,5 +1777,3 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename)
}
/* ------------------------------------------------------------- */
-#endif /* def TCC_TARGET_PE */
-/* ------------------------------------------------------------- */
diff --git a/tccpp.c b/tccpp.c
index ecdaf17..162d081 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -18,6 +18,49 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+ST_DATA int tok_flags;
+/* additional informations about token */
+#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 */
+#define TOK_FLAG_EOF 0x0008 /* end of file */
+
+ST_DATA 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 */
+#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA int *macro_ptr;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+/* ------------------------------------------------------------------------- */
+
+static int *macro_ptr_allocated;
+static int *unget_saved_macro_ptr;
+static int unget_saved_buffer[TOK_MAX_SIZE + 1];
+static int unget_buffer_enabled;
+static TokenSym *hash_ident[TOK_HASH_SIZE];
+static char token_buf[STRING_MAX_SIZE + 1];
+/* true if isid(c) || isnum(c) */
+static unsigned char isidnum_table[256-CH_EOF];
static const char tcc_keywords[] =
#define DEF(id, str) str "\0"
@@ -30,21 +73,115 @@ static const unsigned 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";
-/* true if isid(c) || isnum(c) */
-static unsigned char isidnum_table[256-CH_EOF];
-
-
struct macro_level {
struct macro_level *prev;
int *p;
};
-static void next_nomacro(void);
+ST_FUNC void next_nomacro(void);
static void next_nomacro_spc(void);
-static void macro_subst(TokenString *tok_str, Sym **nested_list,
- const int *macro_str, struct macro_level **can_read_stream);
+static void macro_subst(
+ TokenString *tok_str,
+ Sym **nested_list,
+ const int *macro_str,
+ struct macro_level **can_read_stream
+ );
+
+ST_FUNC void skip(int c)
+{
+ if (tok != c)
+ error("'%c' expected", c);
+ next();
+}
+
+/* ------------------------------------------------------------------------- */
+/* CString handling */
+static void cstr_realloc(CString *cstr, int new_size)
+{
+ int size;
+ void *data;
+
+ size = cstr->size_allocated;
+ if (size == 0)
+ 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);
+ if (!data)
+ error("memory full");
+ cstr->data_allocated = data;
+ cstr->size_allocated = size;
+ cstr->data = data;
+}
+
+/* add a byte */
+ST_INLN void cstr_ccat(CString *cstr, int ch)
+{
+ int size;
+ size = cstr->size + 1;
+ if (size > cstr->size_allocated)
+ cstr_realloc(cstr, size);
+ ((unsigned char *)cstr->data)[size - 1] = ch;
+ cstr->size = size;
+}
+
+ST_FUNC void cstr_cat(CString *cstr, const char *str)
+{
+ int c;
+ for(;;) {
+ c = *str;
+ if (c == '\0')
+ break;
+ cstr_ccat(cstr, c);
+ str++;
+ }
+}
+
+/* add a wide char */
+ST_FUNC void cstr_wccat(CString *cstr, int ch)
+{
+ int size;
+ size = cstr->size + sizeof(nwchar_t);
+ if (size > cstr->size_allocated)
+ cstr_realloc(cstr, size);
+ *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
+ cstr->size = size;
+}
+ST_FUNC void cstr_new(CString *cstr)
+{
+ memset(cstr, 0, sizeof(CString));
+}
+
+/* free string and reset it to NULL */
+ST_FUNC void cstr_free(CString *cstr)
+{
+ tcc_free(cstr->data_allocated);
+ cstr_new(cstr);
+}
+/* XXX: unicode ? */
+ST_FUNC void add_char(CString *cstr, int c)
+{
+ if (c == '\'' || c == '\"' || c == '\\') {
+ /* XXX: could be more precise if char or string */
+ cstr_ccat(cstr, '\\');
+ }
+ if (c >= 32 && c <= 126) {
+ cstr_ccat(cstr, c);
+ } else {
+ cstr_ccat(cstr, '\\');
+ if (c == '\n') {
+ cstr_ccat(cstr, 'n');
+ } else {
+ cstr_ccat(cstr, '0' + ((c >> 6) & 7));
+ cstr_ccat(cstr, '0' + ((c >> 3) & 7));
+ cstr_ccat(cstr, '0' + (c & 7));
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
/* allocate a new token */
static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
{
@@ -82,7 +219,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
#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)
+ST_FUNC TokenSym *tok_alloc(const char *str, int len)
{
TokenSym *ts, **pts;
int i;
@@ -107,7 +244,7 @@ static TokenSym *tok_alloc(const char *str, int len)
/* XXX: buffer overflow */
/* XXX: float tokens */
-char *get_tok_str(int v, CValue *cv)
+ST_FUNC char *get_tok_str(int v, CValue *cv)
{
static char buf[STRING_MAX_SIZE + 1];
static CString cstr_buf;
@@ -243,13 +380,13 @@ static int tcc_peekc_slow(BufferedFile *bf)
/* return the current character, handling end of block if necessary
(but not stray) */
-static int handle_eob(void)
+ST_FUNC int handle_eob(void)
{
return tcc_peekc_slow(file);
}
/* read next char from current input file and handle end of input buffer */
-static inline void inp(void)
+ST_INLN void inp(void)
{
ch = *(++(file->buf_ptr));
/* end of buffer/file handling */
@@ -334,7 +471,7 @@ static int handle_stray1(uint8_t *p)
/* 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)
+ST_FUNC void minp(void)
{
inp();
if (ch == '\\')
@@ -380,7 +517,7 @@ static uint8_t *parse_line_comment(uint8_t *p)
}
/* C comments */
-static uint8_t *parse_comment(uint8_t *p)
+ST_FUNC uint8_t *parse_comment(uint8_t *p)
{
int c;
@@ -537,7 +674,7 @@ static uint8_t *parse_pp_string(uint8_t *p,
/* skip block of text until #else, #elif or #endif. skip also pairs of
#if/#endif */
-void preprocess_skip(void)
+static void preprocess_skip(void)
{
int a, start_of_line, c, in_warn_or_error;
uint8_t *p;
@@ -629,7 +766,7 @@ _default:
files */
/* save current parse state in 's' */
-void save_parse_state(ParseState *s)
+ST_FUNC void save_parse_state(ParseState *s)
{
s->line_num = file->line_num;
s->macro_ptr = macro_ptr;
@@ -638,7 +775,7 @@ void save_parse_state(ParseState *s)
}
/* restore parse state from 's' */
-void restore_parse_state(ParseState *s)
+ST_FUNC void restore_parse_state(ParseState *s)
{
file->line_num = s->line_num;
macro_ptr = s->macro_ptr;
@@ -677,7 +814,7 @@ static inline int tok_ext_size(int t)
/* token string handling */
-static inline void tok_str_new(TokenString *s)
+ST_INLN void tok_str_new(TokenString *s)
{
s->str = NULL;
s->len = 0;
@@ -685,7 +822,7 @@ static inline void tok_str_new(TokenString *s)
s->last_line_num = -1;
}
-static void tok_str_free(int *str)
+ST_FUNC void tok_str_free(int *str)
{
tcc_free(str);
}
@@ -707,7 +844,7 @@ static int *tok_str_realloc(TokenString *s)
return str;
}
-static void tok_str_add(TokenString *s, int t)
+ST_FUNC void tok_str_add(TokenString *s, int t)
{
int len, *str;
@@ -790,7 +927,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
}
/* add the current parse token in token string 's' */
-static void tok_str_add_tok(TokenString *s)
+ST_FUNC void tok_str_add_tok(TokenString *s)
{
CValue cval;
@@ -861,7 +998,7 @@ static void tok_str_add_tok(TokenString *s)
}
/* defines handling */
-static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
{
Sym *s;
@@ -872,7 +1009,7 @@ static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
}
/* undefined a define symbol. Its name is just set to zero */
-static void define_undef(Sym *s)
+ST_FUNC void define_undef(Sym *s)
{
int v;
v = s->v;
@@ -881,7 +1018,7 @@ static void define_undef(Sym *s)
s->v = 0;
}
-static inline Sym *define_find(int v)
+ST_INLN Sym *define_find(int v)
{
v -= TOK_IDENT;
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
@@ -890,7 +1027,7 @@ static inline Sym *define_find(int v)
}
/* free define stack until top reaches 'b' */
-static void free_defines(Sym *b)
+ST_FUNC void free_defines(Sym *b)
{
Sym *top, *top1;
int v;
@@ -911,7 +1048,7 @@ static void free_defines(Sym *b)
}
/* label lookup */
-static Sym *label_find(int v)
+ST_FUNC Sym *label_find(int v)
{
v -= TOK_IDENT;
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
@@ -919,7 +1056,7 @@ static Sym *label_find(int v)
return table_ident[v]->sym_label;
}
-static Sym *label_push(Sym **ptop, int v, int flags)
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
{
Sym *s, **ps;
s = sym_push2(ptop, v, 0, 0);
@@ -938,7 +1075,7 @@ static Sym *label_push(Sym **ptop, int v, int flags)
/* 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)
+ST_FUNC void label_pop(Sym **ptop, Sym *slast)
{
Sym *s, *s1;
for(s = *ptop; s != slast; s = s1) {
@@ -1017,7 +1154,7 @@ static void tok_print(int *str)
#endif
/* parse after #define */
-static void parse_define(void)
+ST_FUNC void parse_define(void)
{
Sym *s, *first, **ps;
int v, t, varg, is_vaargs, spc;
@@ -1193,7 +1330,7 @@ static void pragma_parse(TCCState *s1)
}
/* is_bof is true if first non space token at beginning of file */
-static void preprocess(int is_bof)
+ST_FUNC void preprocess(int is_bof)
{
TCCState *s1 = tcc_state;
int i, c, n, saved_parse_flags;
@@ -1350,7 +1487,7 @@ static void preprocess(int is_bof)
pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1);
file = f;
/* add include file debug info */
- if (tcc_state->do_debug) {
+ if (s1->do_debug) {
put_stabs(file->filename, N_BINCL, 0, 0, 0);
}
tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
@@ -1598,7 +1735,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
#define BN_SIZE 2
/* bn = (bn << shift) | or_val */
-void bn_lshift(unsigned int *bn, int shift, int or_val)
+static void bn_lshift(unsigned int *bn, int shift, int or_val)
{
int i;
unsigned int v;
@@ -1609,7 +1746,7 @@ void bn_lshift(unsigned int *bn, int shift, int or_val)
}
}
-void bn_zero(unsigned int *bn)
+static void bn_zero(unsigned int *bn)
{
int i;
for(i=0;i<BN_SIZE;i++) {
@@ -1619,7 +1756,7 @@ void bn_zero(unsigned int *bn)
/* parse number in null terminated string 'p' and return it in the
current token */
-void parse_number(const char *p)
+static void parse_number(const char *p)
{
int b, t, shift, frac_bits, s, exp_val, ch;
char *q;
@@ -2353,7 +2490,7 @@ static void next_nomacro_spc(void)
}
}
-static void next_nomacro(void)
+ST_FUNC void next_nomacro(void)
{
do {
next_nomacro_spc();
@@ -2734,7 +2871,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list,
}
/* return next token with macro substitution */
-static void next(void)
+ST_FUNC void next(void)
{
Sym *nested_list, *s;
TokenString str;
@@ -2790,7 +2927,7 @@ static void next(void)
/* 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)
+ST_INLN void unget_tok(int last_tok)
{
int i, n;
int *q;
@@ -2809,7 +2946,7 @@ static inline void unget_tok(int last_tok)
/* better than nothing, but needs extension to handle '-E' option
correctly too */
-static void preprocess_init(TCCState *s1)
+ST_FUNC void preprocess_init(TCCState *s1)
{
s1->include_stack_ptr = s1->include_stack;
/* XXX: move that before to avoid having to initialize
@@ -2823,7 +2960,7 @@ static void preprocess_init(TCCState *s1)
s1->pack_stack_ptr = s1->pack_stack;
}
-void preprocess_new()
+ST_FUNC void preprocess_new()
{
int i, c;
const char *p, *r;
@@ -2852,9 +2989,10 @@ void preprocess_new()
}
/* Preprocess the current file */
-static int tcc_preprocess(TCCState *s1)
+ST_FUNC int tcc_preprocess(TCCState *s1)
{
Sym *define_start;
+
BufferedFile *file_ref, **iptr, **iptr_new;
int token_seen, line_ref, d;
const char *s;
@@ -2868,8 +3006,8 @@ static int tcc_preprocess(TCCState *s1)
token_seen = 0;
line_ref = 0;
file_ref = NULL;
-
iptr = s1->include_stack_ptr;
+
for (;;) {
next();
if (tok == TOK_EOF) {
@@ -2904,7 +3042,6 @@ print_line:
}
fputs(get_tok_str(tok, &tokc), s1->outfile);
}
- free_defines(define_start);
+ free_defines(define_start);
return 0;
}
-
diff --git a/tccrun.c b/tccrun.c
index e984c0f..e88f87e 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -1,5 +1,5 @@
/*
- * TCC - Tiny C Compiler
+ * TCC - Tiny C Compiler - Support for -run switch
*
* Copyright (c) 2001-2004 Fabrice Bellard
*
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* tccrun.c - support for tcc -run */
+#include "tcc.h"
#ifdef _WIN32
#define ucontext_t CONTEXT
@@ -26,7 +26,7 @@
static void set_pages_executable(void *ptr, unsigned long length);
static void set_exception_handler(void);
-static int rt_get_caller_pc(unsigned long *paddr, ucontext_t *uc, int level);
+static int rt_get_caller_pc(uplong *paddr, ucontext_t *uc, int level);
static void rt_error(ucontext_t *uc, const char *fmt, ...);
static int tcc_relocate_ex(TCCState *s1, void *ptr);
@@ -173,8 +173,8 @@ static void set_pages_executable(void *ptr, unsigned long length)
VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
#else
unsigned long start, end;
- start = (unsigned long)ptr & ~(PAGESIZE - 1);
- end = (unsigned long)ptr + length;
+ start = (uplong)ptr & ~(PAGESIZE - 1);
+ end = (uplong)ptr + length;
end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
@@ -185,7 +185,7 @@ static void set_pages_executable(void *ptr, unsigned long length)
/* print the position in the source file of PC value 'pc' by reading
the stabs debug information */
-static unsigned long rt_printline(unsigned long wanted_pc)
+static uplong rt_printline(uplong wanted_pc)
{
Stab_Sym *sym, *sym_end;
char func_name[128], last_func_name[128];
@@ -194,7 +194,7 @@ static unsigned long rt_printline(unsigned long wanted_pc)
int incl_index, len, last_line_num, i;
const char *str, *p;
- fprintf(stderr, "0x%08lx:", wanted_pc);
+ fprintf(stderr, "0x%08lx:", (unsigned long)wanted_pc);
func_name[0] = '\0';
func_addr = 0;
@@ -311,7 +311,7 @@ static unsigned long rt_printline(unsigned long wanted_pc)
static void rt_error(ucontext_t *uc, const char *fmt, ...)
{
va_list ap;
- unsigned long pc;
+ uplong pc;
int i;
va_start(ap, fmt);
@@ -327,7 +327,7 @@ static void rt_error(ucontext_t *uc, const char *fmt, ...)
else
fprintf(stderr, "by ");
pc = rt_printline(pc);
- if (pc == (unsigned long)rt_prog_main && pc)
+ if (pc == (uplong)rt_prog_main && pc)
break;
}
exit(255);
@@ -505,11 +505,15 @@ static void set_exception_handler(void)
SetUnhandledExceptionFilter(cpu_exception_handler);
}
+#ifdef _WIN64
+#define Eip Rip
+#define Ebp Rbp
+#endif
+
/* return the PC at frame level 'level'. Return non zero if not found */
-static int rt_get_caller_pc(unsigned long *paddr,
- CONTEXT *uc, int level)
+static int rt_get_caller_pc(uplong *paddr, CONTEXT *uc, int level)
{
- unsigned long fp;
+ uplong fp;
int i;
if (level == 0) {
@@ -521,13 +525,16 @@ static int rt_get_caller_pc(unsigned long *paddr,
/* XXX: check address validity with program info */
if (fp <= 0x1000 || fp >= 0xc0000000)
return -1;
- fp = ((unsigned long *)fp)[0];
+ fp = ((uplong*)fp)[0];
}
- *paddr = ((unsigned long *)fp)[1];
+ *paddr = ((uplong*)fp)[1];
return 0;
}
}
+#undef Eip
+#undef Ebp
+
#endif /* _WIN32 */
#endif /* CONFIG_TCC_BACKTRACE */
/* ------------------------------------------------------------- */
@@ -584,13 +591,7 @@ void *resolve_sym(TCCState *s1, const char *symbol)
return NULL;
}
-#elif defined(_WIN32)
-
-#define dlclose FreeLibrary
-
-#else
-
-#include <dlfcn.h>
+#elif !defined(_WIN32)
void *resolve_sym(TCCState *s1, const char *sym)
{
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 86ec4ea..d9f7528 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -20,10 +20,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <assert.h>
+#ifdef TARGET_DEFS_ONLY
/* number of available registers */
-#define NB_REGS 5
+#define NB_REGS 5
+#define NB_ASM_REGS 8
/* a register can belong to several classes. The classes must be
sorted from more general to more precise (see gv2() code which does
@@ -60,14 +61,6 @@ enum {
#define REX_BASE(reg) (((reg) >> 3) & 1)
#define REG_VALUE(reg) ((reg) & 7)
-const int reg_classes[NB_REGS] = {
- /* eax */ RC_INT | RC_RAX,
- /* ecx */ RC_INT | RC_RCX,
- /* edx */ RC_INT | RC_RDX,
- /* xmm0 */ RC_FLOAT | RC_XMM0,
- /* st0 */ RC_ST0,
-};
-
/* return registers for function */
#define REG_IRET TREG_RAX /* single word int return register */
#define REG_LRET TREG_RDX /* second word return register (for long long) */
@@ -85,6 +78,9 @@ const int reg_classes[NB_REGS] = {
/* maximum alignment (for aligned attribute support) */
#define MAX_ALIGN 8
+ST_FUNC void gen_opl(int op);
+ST_FUNC void gen_le64(int64_t c);
+
/******************************************************/
/* ELF defines */
@@ -100,6 +96,18 @@ const int reg_classes[NB_REGS] = {
#define ELF_PAGE_SIZE 0x1000
/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* eax */ RC_INT | RC_RAX,
+ /* ecx */ RC_INT | RC_RCX,
+ /* edx */ RC_INT | RC_RDX,
+ /* xmm0 */ RC_FLOAT | RC_XMM0,
+ /* st0 */ RC_ST0,
+};
static unsigned long func_sub_sp_offset;
static int func_ret_sub;
@@ -184,7 +192,7 @@ static int is_sse_float(int t) {
}
/* instruction + 4 bytes data. Return the address of the data */
-static int oad(int c, int s)
+ST_FUNC int oad(int c, int s)
{
int ind1;
@@ -198,7 +206,7 @@ static int oad(int c, int s)
return s;
}
-static void gen_addr32(int r, Sym *sym, int c)
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_X86_64_32);
@@ -206,7 +214,7 @@ static void gen_addr32(int r, Sym *sym, int c)
}
/* output constant with relocation if 'r & VT_SYM' is true */
-static void gen_addr64(int r, Sym *sym, int64_t c)
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_X86_64_64);
@@ -214,7 +222,7 @@ static void gen_addr64(int r, Sym *sym, int64_t c)
}
/* output constant with relocation if 'r & VT_SYM' is true */
-static void gen_addrpc32(int r, Sym *sym, int c)
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloc(cur_text_section, sym, ind, R_X86_64_PC32);
@@ -1537,3 +1545,5 @@ void ggoto(void)
/* end of x86-64 code generator */
/*************************************************************/
+#endif /* ! TARGET_DEFS_ONLY */
+/******************************************************/