History

allow tcc be build from separate objects

If you want that, run: make NOTALLINONE=1

grischka committed 16 years ago

Commit 88a3cca1 parent 7fa712e16 files · +1317 −1040Browse files

Unified · Split

16 files
  1. Makefile +26 −13
  2. arm-gen.c +39 −31
  3. c67-gen.c +50 −45
  4. i386-asm.c +11 −9
  5. i386-gen.c +44 −34
  6. libtcc.c +108 −624
  7. tcc.c +16 −16
  8. tcc.h +406 −28
  9. tccasm.c +10 −8
  10. tcccoff.c +3 −1
  11. tccelf.c +27 −35
  12. tccgen.c +290 −52
  13. tccpe.c +62 −67
  14. tccpp.c +179 −42
  15. tccrun.c +22 −21
  16. x86_64-gen.c +24 −14
Makefile+26−13
@@ -113,11 +113,13 @@ ifdef CONFIG_CROSS · 112 unmodified lines
113PROGS+=$(PROGS_CROSS)113PROGS+=$(PROGS_CROSS)
114endif114endif
115 115
116# NOTALLINONE = 1
117
116all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF)118all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF)
117 119
118# Host Tiny C Compiler120# Host Tiny C Compiler
119tcc$(EXESUF): $(NATIVE_FILES)121tcc$(EXESUF): tcc.o libtcc.a
120 $(CC) -o $@ $< $(NATIVE_TARGET) $(CFLAGS) $(LIBS)122 $(CC) -o $@ $^ $(LIBS)
121 123
122# Cross Tiny C Compilers124# Cross Tiny C Compilers
123i386-tcc$(EXESUF): $(I386_FILES)125i386-tcc$(EXESUF): $(I386_FILES)
@@ -151,10 +153,22 @@ arm-tcc-vfp-eabi$(EXESUF): $(ARM_FILES) · 27 unmodified lines
151 $(CC) -o $@ $< -DTCC_TARGET_ARM -DTCC_ARM_EABI $(CFLAGS) $(LIBS)153 $(CC) -o $@ $< -DTCC_TARGET_ARM -DTCC_ARM_EABI $(CFLAGS) $(LIBS)
152 154
153# libtcc generation and test155# libtcc generation and test
154libtcc.o: $(NATIVE_FILES)
155 $(CC) -o $@ -c libtcc.c $(NATIVE_TARGET) $(CFLAGS)
156 156
157libtcc.a: libtcc.o157ifdef NOTALLINONE
158LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
159LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
160$(LIBTCC_OBJ) : DEFINES += -DNOTALLINONE
161else
162LIBTCC_OBJ = libtcc.o
163LIBTCC_INC = $(NATIVE_FILES)
164endif
165
166tcc.o : DEFINES += -DNOTALLINONE
167
168$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
169 $(CC) -o $@ -c $< $(NATIVE_TARGET) $(CFLAGS) $(DEFINES)
170
171libtcc.a: $(LIBTCC_OBJ)
158 $(AR) rcs $@ $^172 $(AR) rcs $@ $^
159 173
160libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a174libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a
@@ -260,19 +274,18 @@ tar: · 99 unmodified lines
260 rm -rf /tmp/$(TCC-VERSION)274 rm -rf /tmp/$(TCC-VERSION)
261 275
262# in tests subdir276# in tests subdir
263test clean:277%est:
264 $(MAKE) -C tests $@278 $(MAKE) -C tests $@
265 279
266config.mak:280clean:
267 @echo Running configure ...
268 @./configure
269
270# clean
271clean: local_clean
272local_clean:
273 rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.out libtcc_test$(EXESUF)281 rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.out libtcc_test$(EXESUF)
282 $(MAKE) -C tests $@
274 283
275distclean: clean284distclean: clean
276 rm -vf config.h config.mak config.texi tcc.1285 rm -vf config.h config.mak config.texi tcc.1
277 286
287config.mak:
288 @echo Running configure ...
289 @./configure
290
278endif # ifeq ($(TOP),.)291endif # ifeq ($(TOP),.)
arm-gen.c+39−31
@@ -20,11 +20,12 @@ · 19 unmodified lines
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */21 */
22 22
23#ifdef TARGET_DEFS_ONLY
24
23#ifdef TCC_ARM_EABI25#ifdef TCC_ARM_EABI
24#define TCC_ARM_VFP26#define TCC_ARM_VFP
25#endif27#endif
26 28
27
28/* number of available registers */29/* number of available registers */
29#ifdef TCC_ARM_VFP30#ifdef TCC_ARM_VFP
30#define NB_REGS 1331#define NB_REGS 13
@@ -75,32 +76,6 @@ enum { · 44 unmodified lines
75#endif76#endif
76};77};
77 78
78const int reg_classes[NB_REGS] = {
79 /* r0 */ RC_INT | RC_R0,
80 /* r1 */ RC_INT | RC_R1,
81 /* r2 */ RC_INT | RC_R2,
82 /* r3 */ RC_INT | RC_R3,
83 /* r12 */ RC_INT | RC_R12,
84 /* f0 */ RC_FLOAT | RC_F0,
85 /* f1 */ RC_FLOAT | RC_F1,
86 /* f2 */ RC_FLOAT | RC_F2,
87 /* f3 */ RC_FLOAT | RC_F3,
88#ifdef TCC_ARM_VFP
89 /* d4/s8 */ RC_FLOAT | RC_F4,
90/* d5/s10 */ RC_FLOAT | RC_F5,
91/* d6/s12 */ RC_FLOAT | RC_F6,
92/* d7/s14 */ RC_FLOAT | RC_F7,
93#endif
94};
95
96static int two2mask(int a,int b) {
97 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
98}
99
100static int regmask(int r) {
101 return reg_classes[r]&~(RC_INT|RC_FLOAT);
102}
103
104#ifdef TCC_ARM_VFP79#ifdef TCC_ARM_VFP
105#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)80#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
106#endif81#endif
@@ -171,10 +146,42 @@ static CType float_type, double_type, func_float_type, func_double_type; · 64 unmodified lines
171#define ELF_PAGE_SIZE 0x1000146#define ELF_PAGE_SIZE 0x1000
172 147
173/******************************************************/148/******************************************************/
149#else /* ! TARGET_DEFS_ONLY */
150/******************************************************/
151#include "tcc.h"
152
153ST_DATA const int reg_classes[NB_REGS] = {
154 /* r0 */ RC_INT | RC_R0,
155 /* r1 */ RC_INT | RC_R1,
156 /* r2 */ RC_INT | RC_R2,
157 /* r3 */ RC_INT | RC_R3,
158 /* r12 */ RC_INT | RC_R12,
159 /* f0 */ RC_FLOAT | RC_F0,
160 /* f1 */ RC_FLOAT | RC_F1,
161 /* f2 */ RC_FLOAT | RC_F2,
162 /* f3 */ RC_FLOAT | RC_F3,
163#ifdef TCC_ARM_VFP
164 /* d4/s8 */ RC_FLOAT | RC_F4,
165/* d5/s10 */ RC_FLOAT | RC_F5,
166/* d6/s12 */ RC_FLOAT | RC_F6,
167/* d7/s14 */ RC_FLOAT | RC_F7,
168#endif
169};
170
174static unsigned long func_sub_sp_offset,last_itod_magic;171static unsigned long func_sub_sp_offset,last_itod_magic;
175static int leaffunc;172static int leaffunc;
176 173
177void o(unsigned long i)174static int two2mask(int a,int b) {
175 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
176}
177
178static int regmask(int r) {
179 return reg_classes[r]&~(RC_INT|RC_FLOAT);
180}
181
182/******************************************************/
183
184void o(unsigned int i)
178{185{
179 /* this is a good place to start adding big-endian support*/186 /* this is a good place to start adding big-endian support*/
180 int ind1;187 int ind1;
@@ -304,7 +311,7 @@ void stuff_const_harder(unsigned long op,unsigned long v) { · 123 unmodified lines
304 }311 }
305}312}
306 313
307unsigned long encbranch(int pos,int addr,int fail)314ST_FUNC unsigned long encbranch(int pos,int addr,int fail)
308{315{
309 addr-=pos+8;316 addr-=pos+8;
310 addr/=4;317 addr/=4;
@@ -1571,7 +1578,7 @@ void gen_opf(int op) · 1260 unmodified lines
1571 1578
1572/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'1579/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
1573 and 'long long' cases. */1580 and 'long long' cases. */
1574void gen_cvt_itof1(int t)1581ST_FUNC void gen_cvt_itof1(int t)
1575{1582{
1576 int r,r2,bt;1583 int r,r2,bt;
1577 bt=vtop->type.t & VT_BTYPE;1584 bt=vtop->type.t & VT_BTYPE;
@@ -1732,4 +1739,5 @@ void ggoto(void) · 154 unmodified lines
1732 1739
1733/* end of ARM code generator */1740/* end of ARM code generator */
1734/*************************************************************/1741/*************************************************************/
1735 1742#endif
1743/*************************************************************/
c67-gen.c+50−45
@@ -18,6 +18,8 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#ifdef TARGET_DEFS_ONLY
22
21//#define ASSEMBLY_LISTING_C6723//#define ASSEMBLY_LISTING_C67
22 24
23/* number of available registers */25/* number of available registers */
@@ -85,62 +87,18 @@ enum { · 61 unmodified lines
85 TREG_C67_B13,87 TREG_C67_B13,
86};88};
87 89
88const int reg_classes[NB_REGS] = {
89 /* eax */ RC_INT | RC_FLOAT | RC_EAX,
90 // only allow even regs for floats (allow for doubles)
91 /* ecx */ RC_INT | RC_ECX,
92 /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
93 // only allow even regs for floats (allow for doubles)
94 /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
95 /* A4 */ RC_C67_A4,
96 /* A5 */ RC_C67_A5,
97 /* B4 */ RC_C67_B4,
98 /* B5 */ RC_C67_B5,
99 /* A6 */ RC_C67_A6,
100 /* A7 */ RC_C67_A7,
101 /* B6 */ RC_C67_B6,
102 /* B7 */ RC_C67_B7,
103 /* A8 */ RC_C67_A8,
104 /* A9 */ RC_C67_A9,
105 /* B8 */ RC_C67_B8,
106 /* B9 */ RC_C67_B9,
107 /* A10 */ RC_C67_A10,
108 /* A11 */ RC_C67_A11,
109 /* B10 */ RC_C67_B10,
110 /* B11 */ RC_C67_B11,
111 /* A12 */ RC_C67_A10,
112 /* A13 */ RC_C67_A11,
113 /* B12 */ RC_C67_B10,
114 /* B13 */ RC_C67_B11
115};
116
117/* return registers for function */90/* return registers for function */
118#define REG_IRET TREG_C67_A4 /* single word int return register */91#define REG_IRET TREG_C67_A4 /* single word int return register */
119#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */92#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */
120#define REG_FRET TREG_C67_A4 /* float return register */93#define REG_FRET TREG_C67_A4 /* float return register */
121 94
122
123#define ALWAYS_ASSERT(x) \95#define ALWAYS_ASSERT(x) \
124do {\96do {\
125 if (!(x))\97 if (!(x))\
126 error("internal compiler error file at %s:%d", __FILE__, __LINE__);\98 error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
127} while (0)99} while (0)
128 100
129// although tcc thinks it is passing parameters on the stack,
130// the C67 really passes up to the first 10 params in special
131// regs or regs pairs (for 64 bit params). So keep track of
132// the stack offsets so we can translate to the appropriate
133// reg (pair)
134
135
136#define NoCallArgsPassedOnStack 10
137int NoOfCurFuncArgs;
138int TranslateStackToReg[NoCallArgsPassedOnStack];
139int ParamLocOnStack[NoCallArgsPassedOnStack];
140int TotalBytesPushedOnStack;
141
142/* defined if function parameters must be evaluated in reverse order */101/* defined if function parameters must be evaluated in reverse order */
143
144//#define INVERT_FUNC_PARAMS102//#define INVERT_FUNC_PARAMS
145 103
146/* defined if structures are passed as pointers. Otherwise structures104/* defined if structures are passed as pointers. Otherwise structures
@@ -171,7 +129,52 @@ int TotalBytesPushedOnStack; · 24 unmodified lines
171#define ELF_PAGE_SIZE 0x1000129#define ELF_PAGE_SIZE 0x1000
172 130
173/******************************************************/131/******************************************************/
132#else /* ! TARGET_DEFS_ONLY */
133/******************************************************/
134#include "tcc.h"
135
136ST_DATA const int reg_classes[NB_REGS] = {
137 /* eax */ RC_INT | RC_FLOAT | RC_EAX,
138 // only allow even regs for floats (allow for doubles)
139 /* ecx */ RC_INT | RC_ECX,
140 /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
141 // only allow even regs for floats (allow for doubles)
142 /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
143 /* A4 */ RC_C67_A4,
144 /* A5 */ RC_C67_A5,
145 /* B4 */ RC_C67_B4,
146 /* B5 */ RC_C67_B5,
147 /* A6 */ RC_C67_A6,
148 /* A7 */ RC_C67_A7,
149 /* B6 */ RC_C67_B6,
150 /* B7 */ RC_C67_B7,
151 /* A8 */ RC_C67_A8,
152 /* A9 */ RC_C67_A9,
153 /* B8 */ RC_C67_B8,
154 /* B9 */ RC_C67_B9,
155 /* A10 */ RC_C67_A10,
156 /* A11 */ RC_C67_A11,
157 /* B10 */ RC_C67_B10,
158 /* B11 */ RC_C67_B11,
159 /* A12 */ RC_C67_A10,
160 /* A13 */ RC_C67_A11,
161 /* B12 */ RC_C67_B10,
162 /* B13 */ RC_C67_B11
163};
164
165// although tcc thinks it is passing parameters on the stack,
166// the C67 really passes up to the first 10 params in special
167// regs or regs pairs (for 64 bit params). So keep track of
168// the stack offsets so we can translate to the appropriate
169// reg (pair)
170
171#define NoCallArgsPassedOnStack 10
172int NoOfCurFuncArgs;
173int TranslateStackToReg[NoCallArgsPassedOnStack];
174int ParamLocOnStack[NoCallArgsPassedOnStack];
175int TotalBytesPushedOnStack;
174 176
177/******************************************************/
175static unsigned long func_sub_sp_offset;178static unsigned long func_sub_sp_offset;
176static int func_ret_sub;179static int func_ret_sub;
177 180
@@ -2545,5 +2548,7 @@ void ggoto(void) · 2367 unmodified lines
2545 vtop--;2548 vtop--;
2546}2549}
2547 2550
2548/* end of X86 code generator */2551/* end of C67 code generator */
2552/*************************************************************/
2553#endif
2549/*************************************************************/2554/*************************************************************/
i386-asm.c+11−9
@@ -19,7 +19,11 @@ · 18 unmodified lines
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */20 */
21 21
22#include "tcc.h"
23
24// #define NB_ASM_REGS 8
22#define MAX_OPERANDS 325#define MAX_OPERANDS 3
26#define NB_SAVED_REGS 3
23 27
24#define TOK_ASM_first TOK_ASM_clc28#define TOK_ASM_first TOK_ASM_clc
25#define TOK_ASM_last TOK_ASM_emms29#define TOK_ASM_last TOK_ASM_emms
@@ -398,7 +402,8 @@ static void parse_operand(TCCState *s1, Operand *op) · 372 unmodified lines
398 op->type |= indir;402 op->type |= indir;
399}403}
400 404
401static void gen_expr32(ExprValue *pe)405/* XXX: unify with C code output ? */
406ST_FUNC void gen_expr32(ExprValue *pe)
402{407{
403 gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);408 gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
404}409}
@@ -554,7 +559,7 @@ static inline void asm_modrm(int reg, Operand *op) · 149 unmodified lines
554 }559 }
555}560}
556 561
557static void asm_opcode(TCCState *s1, int opcode)562ST_FUNC void asm_opcode(TCCState *s1, int opcode)
558{563{
559 const ASMInstr *pa;564 const ASMInstr *pa;
560 int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;565 int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
@@ -966,9 +971,6 @@ static void asm_opcode(TCCState *s1, int opcode) · 405 unmodified lines
966#endif971#endif
967}972}
968 973
969#define NB_SAVED_REGS 3
970#define NB_ASM_REGS 8
971
972/* return the constraint priority (we allocate first the lowest974/* return the constraint priority (we allocate first the lowest
973 numbered constraints) */975 numbered constraints) */
974static inline int constraint_priority(const char *str)976static inline int constraint_priority(const char *str)
@@ -1030,7 +1032,7 @@ static const char *skip_constraint_modifiers(const char *p) · 55 unmodified lines
1030 1032
1031#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)1033#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
1032 1034
1033static void asm_compute_constraints(ASMOperand *operands,1035ST_FUNC void asm_compute_constraints(ASMOperand *operands,
1034 int nb_operands, int nb_outputs,1036 int nb_operands, int nb_outputs,
1035 const uint8_t *clobber_regs,1037 const uint8_t *clobber_regs,
1036 int *pout_reg)1038 int *pout_reg)
@@ -1262,7 +1264,7 @@ static void asm_compute_constraints(ASMOperand *operands, · 225 unmodified lines
1262#endif1264#endif
1263}1265}
1264 1266
1265static void subst_asm_operand(CString *add_str,1267ST_FUNC void subst_asm_operand(CString *add_str,
1266 SValue *sv, int modifier)1268 SValue *sv, int modifier)
1267{1269{
1268 int r, reg, size, val;1270 int r, reg, size, val;
@@ -1356,7 +1358,7 @@ static void subst_asm_operand(CString *add_str, · 87 unmodified lines
1356}1358}
1357 1359
1358/* generate prolog and epilog code for asm statment */1360/* generate prolog and epilog code for asm statment */
1359static void asm_gen_code(ASMOperand *operands, int nb_operands,1361ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
1360 int nb_outputs, int is_output,1362 int nb_outputs, int is_output,
1361 uint8_t *clobber_regs,1363 uint8_t *clobber_regs,
1362 int out_reg)1364 int out_reg)
@@ -1450,7 +1452,7 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, · 87 unmodified lines
1450 }1452 }
1451}1453}
1452 1454
1453static void asm_clobber(uint8_t *clobber_regs, const char *str)1455ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
1454{1456{
1455 int reg;1457 int reg;
1456 TokenSym *ts;1458 TokenSym *ts;
i386-gen.c+44−34
@@ -18,8 +18,11 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#ifdef TARGET_DEFS_ONLY
22
21/* number of available registers */23/* number of available registers */
22#define NB_REGS 424#define NB_REGS 4
25#define NB_ASM_REGS 8
23 26
24/* a register can belong to several classes. The classes must be27/* a register can belong to several classes. The classes must be
25 sorted from more general to more precise (see gv2() code which does28 sorted from more general to more precise (see gv2() code which does
@@ -42,13 +45,6 @@ enum { · 16 unmodified lines
42 TREG_ST0,45 TREG_ST0,
43};46};
44 47
45const int reg_classes[NB_REGS] = {
46 /* eax */ RC_INT | RC_EAX,
47 /* ecx */ RC_INT | RC_ECX,
48 /* edx */ RC_INT | RC_EDX,
49 /* st0 */ RC_FLOAT | RC_ST0,
50};
51
52/* return registers for function */48/* return registers for function */
53#define REG_IRET TREG_EAX /* single word int return register */49#define REG_IRET TREG_EAX /* single word int return register */
54#define REG_LRET TREG_EDX /* second word return register (for long long) */50#define REG_LRET TREG_EDX /* second word return register (for long long) */
@@ -70,6 +66,9 @@ const int reg_classes[NB_REGS] = { · 15 unmodified lines
70/* maximum alignment (for aligned attribute support) */66/* maximum alignment (for aligned attribute support) */
71#define MAX_ALIGN 867#define MAX_ALIGN 8
72 68
69
70#define psym oad
71
73/******************************************************/72/******************************************************/
74/* ELF defines */73/* ELF defines */
75 74
@@ -85,6 +84,16 @@ const int reg_classes[NB_REGS] = { · 9 unmodified lines
85#define ELF_PAGE_SIZE 0x100084#define ELF_PAGE_SIZE 0x1000
86 85
87/******************************************************/86/******************************************************/
87#else /* ! TARGET_DEFS_ONLY */
88/******************************************************/
89#include "tcc.h"
90
91ST_DATA const int reg_classes[NB_REGS] = {
92 /* eax */ RC_INT | RC_EAX,
93 /* ecx */ RC_INT | RC_ECX,
94 /* edx */ RC_INT | RC_EDX,
95 /* st0 */ RC_FLOAT | RC_ST0,
96};
88 97
89static unsigned long func_sub_sp_offset;98static unsigned long func_sub_sp_offset;
90static int func_ret_sub;99static int func_ret_sub;
@@ -93,7 +102,7 @@ static unsigned long func_bound_offset; · 2 unmodified lines
93#endif102#endif
94 103
95/* XXX: make it faster ? */104/* XXX: make it faster ? */
96void g(int c)105ST_FUNC void g(int c)
97{106{
98 int ind1;107 int ind1;
99 ind1 = ind + 1;108 ind1 = ind + 1;
@@ -103,7 +112,7 @@ void g(int c) · 3 unmodified lines
103 ind = ind1;112 ind = ind1;
104}113}
105 114
106void o(unsigned int c)115ST_FUNC void o(unsigned int c)
107{116{
108 while (c) {117 while (c) {
109 g(c);118 g(c);
@@ -111,13 +120,13 @@ void o(unsigned int c) · 1 unmodified line
111 }120 }
112}121}
113 122
114void gen_le16(int v)123ST_FUNC void gen_le16(int v)
115{124{
116 g(v);125 g(v);
117 g(v >> 8);126 g(v >> 8);
118}127}
119 128
120void gen_le32(int c)129ST_FUNC void gen_le32(int c)
121{130{
122 g(c);131 g(c);
123 g(c >> 8);132 g(c >> 8);
@@ -126,7 +135,7 @@ void gen_le32(int c) · 2 unmodified lines
126}135}
127 136
128/* output a symbol and patch all calls to it */137/* output a symbol and patch all calls to it */
129void gsym_addr(int t, int a)138ST_FUNC void gsym_addr(int t, int a)
130{139{
131 int n, *ptr;140 int n, *ptr;
132 while (t) {141 while (t) {
@@ -137,7 +146,7 @@ void gsym_addr(int t, int a) · 4 unmodified lines
137 }146 }
138}147}
139 148
140void gsym(int t)149ST_FUNC void gsym(int t)
141{150{
142 gsym_addr(t, ind);151 gsym_addr(t, ind);
143}152}
@@ -147,7 +156,7 @@ void gsym(int t) · 3 unmodified lines
147#define psym oad156#define psym oad
148 157
149/* instruction + 4 bytes data. Return the address of the data */158/* instruction + 4 bytes data. Return the address of the data */
150static int oad(int c, int s)159ST_FUNC int oad(int c, int s)
151{160{
152 int ind1;161 int ind1;
153 162
@@ -162,14 +171,14 @@ static int oad(int c, int s) · 8 unmodified lines
162}171}
163 172
164/* output constant with relocation if 'r & VT_SYM' is true */173/* output constant with relocation if 'r & VT_SYM' is true */
165static void gen_addr32(int r, Sym *sym, int c)174ST_FUNC void gen_addr32(int r, Sym *sym, int c)
166{175{
167 if (r & VT_SYM)176 if (r & VT_SYM)
168 greloc(cur_text_section, sym, ind, R_386_32);177 greloc(cur_text_section, sym, ind, R_386_32);
169 gen_le32(c);178 gen_le32(c);
170}179}
171 180
172static void gen_addrpc32(int r, Sym *sym, int c)181ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
173{182{
174 if (r & VT_SYM)183 if (r & VT_SYM)
175 greloc(cur_text_section, sym, ind, R_386_PC32);184 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) · 24 unmodified lines
200}209}
201 210
202/* load 'r' from value 'sv' */211/* load 'r' from value 'sv' */
203void load(int r, SValue *sv)212ST_FUNC void load(int r, SValue *sv)
204{213{
205 int v, t, ft, fc, fr;214 int v, t, ft, fc, fr;
206 SValue v1;215 SValue v1;
@@ -269,7 +278,7 @@ void load(int r, SValue *sv) · 62 unmodified lines
269}278}
270 279
271/* store register 'r' in lvalue 'v' */280/* store register 'r' in lvalue 'v' */
272void store(int r, SValue *v)281ST_FUNC void store(int r, SValue *v)
273{282{
274 int fr, bt, ft, fc;283 int fr, bt, ft, fc;
275 284
@@ -349,7 +358,7 @@ static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX }; · 73 unmodified lines
349/* Generate function call. The function address is pushed first, then358/* Generate function call. The function address is pushed first, then
350 all the parameters in call order. This functions pops all the359 all the parameters in call order. This functions pops all the
351 parameters and the function address. */360 parameters and the function address. */
352void gfunc_call(int nb_args)361ST_FUNC void gfunc_call(int nb_args)
353{362{
354 int size, align, r, args_size, i, func_call;363 int size, align, r, args_size, i, func_call;
355 Sym *func_sym;364 Sym *func_sym;
@@ -442,7 +451,7 @@ void gfunc_call(int nb_args) · 86 unmodified lines
442#endif451#endif
443 452
444/* generate function prolog of type 't' */453/* generate function prolog of type 't' */
445void gfunc_prolog(CType *func_type)454ST_FUNC void gfunc_prolog(CType *func_type)
446{455{
447 int addr, align, size, func_call, fastcall_nb_regs;456 int addr, align, size, func_call, fastcall_nb_regs;
448 int param_index, param_addr;457 int param_index, param_addr;
@@ -524,7 +533,7 @@ void gfunc_prolog(CType *func_type) · 75 unmodified lines
524}533}
525 534
526/* generate function epilog */535/* generate function epilog */
527void gfunc_epilog(void)536ST_FUNC void gfunc_epilog(void)
528{537{
529 int v, saved_ind;538 int v, saved_ind;
530 539
@@ -595,13 +604,13 @@ void gfunc_epilog(void) · 64 unmodified lines
595}604}
596 605
597/* generate a jump to a label */606/* generate a jump to a label */
598int gjmp(int t)607ST_FUNC int gjmp(int t)
599{608{
600 return psym(0xe9, t);609 return psym(0xe9, t);
601}610}
602 611
603/* generate a jump to a fixed address */612/* generate a jump to a fixed address */
604void gjmp_addr(int a)613ST_FUNC void gjmp_addr(int a)
605{614{
606 int r;615 int r;
607 r = a - ind - 2;616 r = a - ind - 2;
@@ -614,7 +623,7 @@ void gjmp_addr(int a) · 6 unmodified lines
614}623}
615 624
616/* generate a test. set 'inv' to invert test. Stack entry is popped */625/* generate a test. set 'inv' to invert test. Stack entry is popped */
617int gtst(int inv, int t)626ST_FUNC int gtst(int inv, int t)
618{627{
619 int v, *p;628 int v, *p;
620 629
@@ -659,7 +668,7 @@ int gtst(int inv, int t) · 38 unmodified lines
659}668}
660 669
661/* generate an integer binary operation */670/* generate an integer binary operation */
662void gen_opi(int op)671ST_FUNC void gen_opi(int op)
663{672{
664 int r, fr, opc, c;673 int r, fr, opc, c;
665 674
@@ -793,7 +802,7 @@ void gen_opi(int op) · 127 unmodified lines
793/* generate a floating point operation 'v = t1 op t2' instruction. The802/* generate a floating point operation 'v = t1 op t2' instruction. The
794 two operands are guaranted to have the same floating point type */803 two operands are guaranted to have the same floating point type */
795/* XXX: need to use ST1 too */804/* XXX: need to use ST1 too */
796void gen_opf(int op)805ST_FUNC void gen_opf(int op)
797{806{
798 int a, ft, fc, swapped, r;807 int a, ft, fc, swapped, r;
799 808
@@ -905,7 +914,7 @@ void gen_opf(int op) · 105 unmodified lines
905 914
906/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'915/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
907 and 'long long' cases. */916 and 'long long' cases. */
908void gen_cvt_itof(int t)917ST_FUNC void gen_cvt_itof(int t)
909{918{
910 save_reg(TREG_ST0);919 save_reg(TREG_ST0);
911 gv(RC_INT);920 gv(RC_INT);
@@ -935,7 +944,7 @@ void gen_cvt_itof(int t) · 23 unmodified lines
935 944
936/* convert fp to int 't' type */945/* convert fp to int 't' type */
937/* XXX: handle long long case */946/* XXX: handle long long case */
938void gen_cvt_ftoi(int t)947ST_FUNC void gen_cvt_ftoi(int t)
939{948{
940 int r, r2, size;949 int r, r2, size;
941 Sym *sym;950 Sym *sym;
@@ -986,14 +995,14 @@ void gen_cvt_ftoi(int t) · 44 unmodified lines
986}995}
987 996
988/* convert from one floating point type to another */997/* convert from one floating point type to another */
989void gen_cvt_ftof(int t)998ST_FUNC void gen_cvt_ftof(int t)
990{999{
991 /* all we have to do on i386 is to put the float in a register */1000 /* all we have to do on i386 is to put the float in a register */
992 gv(RC_FLOAT);1001 gv(RC_FLOAT);
993}1002}
994 1003
995/* computed goto support */1004/* computed goto support */
996void ggoto(void)1005ST_FUNC void ggoto(void)
997{1006{
998 gcall_or_jmp(1);1007 gcall_or_jmp(1);
999 vtop--;1008 vtop--;
@@ -1003,7 +1012,7 @@ void ggoto(void) · 3 unmodified lines
1003#ifdef CONFIG_TCC_BCHECK1012#ifdef CONFIG_TCC_BCHECK
1004 1013
1005/* generate a bounded pointer addition */1014/* generate a bounded pointer addition */
1006void gen_bounded_ptr_add(void)1015ST_FUNC void gen_bounded_ptr_add(void)
1007{1016{
1008 Sym *sym;1017 Sym *sym;
1009 1018
@@ -1026,7 +1035,7 @@ void gen_bounded_ptr_add(void) · 16 unmodified lines
1026 1035
1027/* patch pointer addition in vtop so that pointer dereferencing is1036/* patch pointer addition in vtop so that pointer dereferencing is
1028 also tested */1037 also tested */
1029void gen_bounded_ptr_deref(void)1038ST_FUNC void gen_bounded_ptr_deref(void)
1030{1039{
1031 int func;1040 int func;
1032 int size, align;1041 int size, align;
@@ -1068,4 +1077,5 @@ void gen_bounded_ptr_deref(void) · 35 unmodified lines
1068 1077
1069/* end of X86 code generator */1078/* end of X86 code generator */
1070/*************************************************************/1079/*************************************************************/
1071 1080#endif
1081/*************************************************************/
libtcc.c+108−624
@@ -23,344 +23,70 @@ · 22 unmodified lines
23/********************************************************/23/********************************************************/
24/* global variables */24/* global variables */
25 25
26/* display benchmark infos */
27int total_lines;
28int total_bytes;
29
30/* parser */
31static struct BufferedFile *file;
32static int ch, tok;
33static CValue tokc;
34static CString tokcstr; /* current parsed string, if any */
35/* additional informations about token */
36static int tok_flags;
37#define TOK_FLAG_BOL 0x0001 /* beginning of line before */
38#define TOK_FLAG_BOF 0x0002 /* beginning of file before */
39#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
40#define TOK_FLAG_EOF 0x0008 /* end of file */
41
42static int *macro_ptr, *macro_ptr_allocated;
43static int *unget_saved_macro_ptr;
44static int unget_saved_buffer[TOK_MAX_SIZE + 1];
45static int unget_buffer_enabled;
46static int parse_flags;
47#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
48#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
49#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
50 token. line feed is also
51 returned at eof */
52#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
53#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
54
55static Section *text_section, *data_section, *bss_section; /* predefined sections */
56static Section *cur_text_section; /* current section where function code is
57 generated */
58#ifdef CONFIG_TCC_ASM
59static Section *last_text_section; /* to handle .previous asm directive */
60#endif
61
62#ifdef CONFIG_TCC_BCHECK
63/* bound check related sections */
64static Section *bounds_section; /* contains global data bound description */
65static Section *lbounds_section; /* contains local data bound description */
66#endif
67
68/* symbol sections */
69static Section *symtab_section, *strtab_section;
70
71/* debug sections */
72static Section *stab_section, *stabstr_section;
73
74/* loc : local variable index
75 ind : output code index
76 rsym: return symbol
77 anon_sym: anonymous symbol index
78*/
79static int rsym, anon_sym, ind, loc;
80/* expression generation modifiers */
81static int const_wanted; /* true if constant wanted */
82static int nocode_wanted; /* true if no code generation wanted for an expression */
83static int global_expr; /* true if compound literals must be allocated
84 globally (used during initializers parsing */
85static CType func_vt; /* current function return type (used by return
86 instruction) */
87static int func_vc;
88static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
89static int tok_ident;
90static TokenSym **table_ident;
91static TokenSym *hash_ident[TOK_HASH_SIZE];
92static char token_buf[STRING_MAX_SIZE + 1];
93static char *funcname;
94static Sym *global_stack, *local_stack;
95static Sym *define_stack;
96static Sym *global_label_stack, *local_label_stack;
97/* symbol allocator */
98#define SYM_POOL_NB (8192 / sizeof(Sym))
99static Sym *sym_free_first;
100static void **sym_pools;
101static int nb_sym_pools;
102
103static SValue vstack[VSTACK_SIZE], *vtop;
104/* some predefined types */
105static CType char_pointer_type, func_old_type, int_type;
106
107/* use GNU C extensions */26/* use GNU C extensions */
108static int gnu_ext = 1;27ST_DATA int gnu_ext = 1;
109 28
110/* use Tiny C extensions */29/* use TinyCC extensions */
111static int tcc_ext = 1;30ST_DATA int tcc_ext = 1;
112
113/* max number of callers shown if error */
114#ifdef CONFIG_TCC_BACKTRACE
115int num_callers = 6;
116void *rt_prog_main;
117const char **rt_bound_error_msg;
118#endif
119 31
120/* XXX: get rid of this ASAP */32/* XXX: get rid of this ASAP */
121static struct TCCState *tcc_state;33ST_DATA struct TCCState *tcc_state;
122
123/********************************************************/
124/* function prototypes */
125
126/* tccpp.c */
127static void next(void);
128char *get_tok_str(int v, CValue *cv);
129
130/* tccgen.c */
131static void parse_expr_type(CType *type);
132static void expr_type(CType *type);
133static void unary_type(CType *type);
134static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
135 int case_reg, int is_expr);
136static int expr_const(void);
137static void expr_eq(void);
138static void gexpr(void);
139static void gen_inline_functions(void);
140static void decl(int l);
141static void decl_initializer(CType *type, Section *sec, unsigned long c,
142 int first, int size_only);
143static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
144 int has_init, int v, int scope);
145int gv(int rc);
146void gv2(int rc1, int rc2);
147void move_reg(int r, int s);
148void save_regs(int n);
149void save_reg(int r);
150void vpop(void);
151void vswap(void);
152void vdup(void);
153int get_reg(int rc);
154int get_reg_ex(int rc,int rc2);
155
156void gen_op(int op);
157void force_charshort_cast(int t);
158static void gen_cast(CType *type);
159void vstore(void);
160static Sym *sym_find(int v);
161static Sym *sym_push(int v, CType *type, int r, int c);
162
163/* type handling */
164static int type_size(CType *type, int *a);
165static inline CType *pointed_type(CType *type);
166static int pointed_size(CType *type);
167static int lvalue_type(int t);
168static int parse_btype(CType *type, AttributeDef *ad);
169static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
170static int compare_types(CType *type1, CType *type2, int unqualified);
171static int is_compatible_types(CType *type1, CType *type2);
172static int is_compatible_parameter_types(CType *type1, CType *type2);
173
174int ieee_finite(double d);
175void vpushi(int v);
176void vpushll(long long v);
177void vrott(int n);
178void vnrott(int n);
179void lexpand_nr(void);
180static void vpush_global_sym(CType *type, int v);
181void vset(CType *type, int r, int v);
182void type_to_str(char *buf, int buf_size,
183 CType *type, const char *varstr);
184static Sym *get_sym_ref(CType *type, Section *sec,
185 unsigned long offset, unsigned long size);
186static Sym *external_global_sym(int v, CType *type, int r);
187
188/* section generation */
189static void section_realloc(Section *sec, unsigned long new_size);
190static void *section_ptr_add(Section *sec, unsigned long size);
191static void put_extern_sym(Sym *sym, Section *section,
192 unsigned long value, unsigned long size);
193static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
194static int put_elf_str(Section *s, const char *sym);
195static int put_elf_sym(Section *s,
196 unsigned long value, unsigned long size,
197 int info, int other, int shndx, const char *name);
198static int add_elf_sym(Section *s, uplong value, unsigned long size,
199 int info, int other, int sh_num, const char *name);
200static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
201 int type, int symbol);
202static void put_stabs(const char *str, int type, int other, int desc,
203 unsigned long value);
204static void put_stabs_r(const char *str, int type, int other, int desc,
205 unsigned long value, Section *sec, int sym_index);
206static void put_stabn(int type, int other, int desc, int value);
207static void put_stabd(int type, int other, int desc);
208static int tcc_add_dll(TCCState *s, const char *filename, int flags);
209
210#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
211#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
212#define AFF_PREPROCESS 0x0004 /* preprocess file */
213static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
214
215/* tcccoff.c */
216int tcc_output_coff(TCCState *s1, FILE *f);
217
218/* tccpe.c */
219int pe_load_file(struct TCCState *s1, const char *filename, int fd);
220int pe_output_file(struct TCCState *s1, const char *filename);
221int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv));
222
223/* tccasm.c */
224#ifdef CONFIG_TCC_ASM
225static void asm_expr(TCCState *s1, ExprValue *pe);
226static int asm_int_expr(TCCState *s1);
227static int find_constraint(ASMOperand *operands, int nb_operands,
228 const char *name, const char **pp);
229 34
230static int tcc_assemble(TCCState *s1, int do_preprocess);35#ifdef CONFIG_TCC_BACKTRACE
36ST_DATA int num_callers = 6;
37ST_DATA const char **rt_bound_error_msg;
38ST_DATA void *rt_prog_main;
231#endif39#endif
232 40
233static void asm_instr(void);
234static void asm_global_instr(void);
235
236/********************************************************/
237/* libtcc.c */
238
239static Sym *__sym_malloc(void);
240static inline Sym *sym_malloc(void);
241static inline void sym_free(Sym *sym);
242Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
243static void free_section(Section *s);
244static void section_realloc(Section *sec, unsigned long new_size);
245static void *section_ptr_add(Section *sec, unsigned long size);
246Section *find_section(TCCState *s1, const char *name);
247static void put_extern_sym2(
248 Sym *sym, Section *section,
249 unsigned long value, unsigned long size, int can_add_underscore);
250static void put_extern_sym(
251 Sym *sym, Section *section,
252 unsigned long value, unsigned long size);
253static void greloc(Section *s, Sym *sym, unsigned long offset, int type);
254
255static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap);
256static void strcat_printf(char *buf, int buf_size, const char *fmt, ...);
257
258/* CString handling */
259static void cstr_realloc(CString *cstr, int new_size);
260static inline void cstr_ccat(CString *cstr, int ch);
261static void cstr_cat(CString *cstr, const char *str);
262static void cstr_wccat(CString *cstr, int ch);
263static void cstr_new(CString *cstr);
264static void cstr_free(CString *cstr);
265#define cstr_reset(cstr) cstr_free(cstr)
266static void add_char(CString *cstr, int c);
267
268static Sym *sym_push2(Sym **ps, int v, int t, long c);
269static Sym *sym_find2(Sym *s, int v);
270static inline Sym *struct_find(int v);
271static inline Sym *sym_find(int v);
272static Sym *sym_push(int v, CType *type, int r, int c);
273static Sym *global_identifier_push(int v, int t, int c);
274static void sym_pop(Sym **ptop, Sym *b);
275
276BufferedFile *tcc_open(TCCState *s1, const char *filename);
277void tcc_close(BufferedFile *bf);
278static int tcc_compile(TCCState *s1);
279
280void expect(const char *msg);
281void skip(int c);
282static void test_lvalue(void);
283void *resolve_sym(TCCState *s1, const char *sym);
284
285static inline int isid(int c)
286{
287 return (c >= 'a' && c <= 'z')
288 || (c >= 'A' && c <= 'Z')
289 || c == '_';
290}
291
292static inline int isnum(int c)
293{
294 return c >= '0' && c <= '9';
295}
296
297static inline int isoct(int c)
298{
299 return c >= '0' && c <= '7';
300}
301
302static inline int toup(int c)
303{
304 if (c >= 'a' && c <= 'z')
305 return c - 'a' + 'A';
306 else
307 return c;
308}
309
310/********************************************************/41/********************************************************/
311 42
43#ifndef NOTALLINONE
44#include "tccpp.c"
45#include "tccgen.c"
46#include "tccelf.c"
47#include "tccrun.c"
312#ifdef TCC_TARGET_I38648#ifdef TCC_TARGET_I386
313#include "i386-gen.c"49#include "i386-gen.c"
314#endif50#endif
315
316#ifdef TCC_TARGET_ARM51#ifdef TCC_TARGET_ARM
317#include "arm-gen.c"52#include "arm-gen.c"
318#endif53#endif
319
320#ifdef TCC_TARGET_C6754#ifdef TCC_TARGET_C67
321#include "c67-gen.c"55#include "c67-gen.c"
322#endif56#endif
323
324#ifdef TCC_TARGET_X86_6457#ifdef TCC_TARGET_X86_64
325#include "x86_64-gen.c"58#include "x86_64-gen.c"
326#endif59#endif
327
328#include "tccpp.c"
329#include "tccgen.c"
330
331#ifdef CONFIG_TCC_ASM60#ifdef CONFIG_TCC_ASM
332 61#include "tccasm.c"
333#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_6462#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
334#include "i386-asm.c"63#include "i386-asm.c"
335#endif64#endif
336
337#include "tccasm.c"
338#else
339static void asm_instr(void)
340{
341 error("inline asm() not supported");
342}
343static void asm_global_instr(void)
344{
345 error("inline asm() not supported");
346}
347#endif65#endif
348
349#include "tccelf.c"
350
351#ifdef TCC_TARGET_COFF66#ifdef TCC_TARGET_COFF
352#include "tcccoff.c"67#include "tcccoff.c"
353#endif68#endif
354
355#ifdef TCC_TARGET_PE69#ifdef TCC_TARGET_PE
356#include "tccpe.c"70#include "tccpe.c"
357#endif71#endif
72#endif /* ALL_IN_ONE */
358 73
359#include "tccrun.c"74/********************************************************/
75#ifndef CONFIG_TCC_ASM
76ST_FUNC void asm_instr(void)
77{
78 error("inline asm() not supported");
79}
80ST_FUNC void asm_global_instr(void)
81{
82 error("inline asm() not supported");
83}
84#endif
360 85
361/********************************************************/86/********************************************************/
87
362#ifdef _WIN3288#ifdef _WIN32
363char *normalize_slashes(char *path)89static char *normalize_slashes(char *path)
364{90{
365 char *p;91 char *p;
366 for (p = path; *p; ++p)92 for (p = path; *p; ++p)
@@ -369,10 +95,10 @@ char *normalize_slashes(char *path) · 2 unmodified lines
369 return path;95 return path;
370}96}
371 97
372HMODULE tcc_module;98static HMODULE tcc_module;
373 99
374/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */100/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
375void tcc_set_lib_path_w32(TCCState *s)101static void tcc_set_lib_path_w32(TCCState *s)
376{102{
377 char path[1024], *p;103 char path[1024], *p;
378 GetModuleFileNameA(tcc_module, path, sizeof path);104 GetModuleFileNameA(tcc_module, path, sizeof path);
@@ -396,18 +122,8 @@ BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) · 17 unmodified lines
396#endif122#endif
397 123
398/********************************************************/124/********************************************************/
399
400/* we use our own 'finite' function to avoid potential problems with
401 non standard math libs */
402/* XXX: endianness dependent */
403int ieee_finite(double d)
404{
405 int *p = (int *)&d;
406 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
407}
408
409/* copy a string and truncate it. */125/* copy a string and truncate it. */
410char *pstrcpy(char *buf, int buf_size, const char *s)126PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
411{127{
412 char *q, *q_end;128 char *q, *q_end;
413 int c;129 int c;
@@ -427,7 +143,7 @@ char *pstrcpy(char *buf, int buf_size, const char *s) · 13 unmodified lines
427}143}
428 144
429/* strcat and truncate. */145/* strcat and truncate. */
430char *pstrcat(char *buf, int buf_size, const char *s)146PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
431{147{
432 int len;148 int len;
433 len = strlen(buf);149 len = strlen(buf);
@@ -437,7 +153,7 @@ char *pstrcat(char *buf, int buf_size, const char *s) · 3 unmodified lines
437}153}
438 154
439/* extract the basename of a file */155/* extract the basename of a file */
440char *tcc_basename(const char *name)156PUB_FUNC char *tcc_basename(const char *name)
441{157{
442 char *p = strchr(name, 0);158 char *p = strchr(name, 0);
443 while (p > name && !IS_PATHSEP(p[-1]))159 while (p > name && !IS_PATHSEP(p[-1]))
@@ -445,21 +161,27 @@ char *tcc_basename(const char *name) · 1 unmodified line
445 return p;161 return p;
446}162}
447 163
448char *tcc_fileextension (const char *name)164PUB_FUNC char *tcc_fileextension (const char *name)
449{165{
450 char *b = tcc_basename(name);166 char *b = tcc_basename(name);
451 char *e = strrchr(b, '.');167 char *e = strrchr(b, '.');
452 return e ? e : strchr(b, 0);168 return e ? e : strchr(b, 0);
453}169}
454 170
171/********************************************************/
455/* memory management */172/* memory management */
173
174#undef free
175#undef malloc
176#undef realloc
177
456#ifdef MEM_DEBUG178#ifdef MEM_DEBUG
457int mem_cur_size;179int mem_cur_size;
458int mem_max_size;180int mem_max_size;
459unsigned malloc_usable_size(void*);181unsigned malloc_usable_size(void*);
460#endif182#endif
461 183
462void tcc_free(void *ptr)184PUB_FUNC void tcc_free(void *ptr)
463{185{
464#ifdef MEM_DEBUG186#ifdef MEM_DEBUG
465 mem_cur_size -= malloc_usable_size(ptr);187 mem_cur_size -= malloc_usable_size(ptr);
@@ -467,7 +189,7 @@ void tcc_free(void *ptr) · 1 unmodified line
467 free(ptr);189 free(ptr);
468}190}
469 191
470void *tcc_malloc(unsigned long size)192PUB_FUNC void *tcc_malloc(unsigned long size)
471{193{
472 void *ptr;194 void *ptr;
473 ptr = malloc(size);195 ptr = malloc(size);
@@ -481,7 +203,7 @@ void *tcc_malloc(unsigned long size) · 7 unmodified lines
481 return ptr;203 return ptr;
482}204}
483 205
484void *tcc_mallocz(unsigned long size)206PUB_FUNC void *tcc_mallocz(unsigned long size)
485{207{
486 void *ptr;208 void *ptr;
487 ptr = tcc_malloc(size);209 ptr = tcc_malloc(size);
@@ -489,7 +211,7 @@ void *tcc_mallocz(unsigned long size) · 1 unmodified line
489 return ptr;211 return ptr;
490}212}
491 213
492void *tcc_realloc(void *ptr, unsigned long size)214PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
493{215{
494 void *ptr1;216 void *ptr1;
495#ifdef MEM_DEBUG217#ifdef MEM_DEBUG
@@ -505,7 +227,7 @@ void *tcc_realloc(void *ptr, unsigned long size) · 9 unmodified lines
505 return ptr1;227 return ptr1;
506}228}
507 229
508char *tcc_strdup(const char *str)230PUB_FUNC char *tcc_strdup(const char *str)
509{231{
510 char *ptr;232 char *ptr;
511 ptr = tcc_malloc(strlen(str) + 1);233 ptr = tcc_malloc(strlen(str) + 1);
@@ -513,7 +235,7 @@ char *tcc_strdup(const char *str) · 1 unmodified line
513 return ptr;235 return ptr;
514}236}
515 237
516void tcc_memstats(void)238PUB_FUNC void tcc_memstats(void)
517{239{
518#ifdef MEM_DEBUG240#ifdef MEM_DEBUG
519 printf("memory in use: %d\n", mem_cur_size);241 printf("memory in use: %d\n", mem_cur_size);
@@ -524,7 +246,10 @@ void tcc_memstats(void) · 4 unmodified lines
524#define malloc(s) use_tcc_malloc(s)246#define malloc(s) use_tcc_malloc(s)
525#define realloc(p, s) use_tcc_realloc(p, s)247#define realloc(p, s) use_tcc_realloc(p, s)
526 248
527void dynarray_add(void ***ptab, int *nb_ptr, void *data)249/********************************************************/
250/* dynarrays */
251
252PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
528{253{
529 int nb, nb_alloc;254 int nb, nb_alloc;
530 void **pp;255 void **pp;
@@ -546,7 +271,7 @@ void dynarray_add(void ***ptab, int *nb_ptr, void *data) · 15 unmodified lines
546 *nb_ptr = nb;271 *nb_ptr = nb;
547}272}
548 273
549void dynarray_reset(void *pp, int *n)274PUB_FUNC void dynarray_reset(void *pp, int *n)
550{275{
551 void **p;276 void **p;
552 for (p = *(void***)pp; *n; ++p, --*n)277 for (p = *(void***)pp; *n; ++p, --*n)
@@ -556,43 +281,18 @@ void dynarray_reset(void *pp, int *n) · 3 unmodified lines
556 *(void**)pp = NULL;281 *(void**)pp = NULL;
557}282}
558 283
559/* symbol allocator */284/* we use our own 'finite' function to avoid potential problems with
560static Sym *__sym_malloc(void)285 non standard math libs */
561{286/* XXX: endianness dependent */
562 Sym *sym_pool, *sym, *last_sym;287ST_FUNC int ieee_finite(double d)
563 int i;
564
565 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
566 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
567
568 last_sym = sym_free_first;
569 sym = sym_pool;
570 for(i = 0; i < SYM_POOL_NB; i++) {
571 sym->next = last_sym;
572 last_sym = sym;
573 sym++;
574 }
575 sym_free_first = last_sym;
576 return last_sym;
577}
578
579static inline Sym *sym_malloc(void)
580{288{
581 Sym *sym;289 int *p = (int *)&d;
582 sym = sym_free_first;290 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
583 if (!sym)
584 sym = __sym_malloc();
585 sym_free_first = sym->next;
586 return sym;
587}291}
588 292
589static inline void sym_free(Sym *sym)293/********************************************************/
590{
591 sym->next = sym_free_first;
592 sym_free_first = sym;
593}
594 294
595Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)295ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
596{296{
597 Section *sec;297 Section *sec;
598 298
@@ -633,7 +333,7 @@ static void free_section(Section *s) · 34 unmodified lines
633}333}
634 334
635/* realloc section and set its content to zero */335/* realloc section and set its content to zero */
636static void section_realloc(Section *sec, unsigned long new_size)336ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
637{337{
638 unsigned long size;338 unsigned long size;
639 unsigned char *data;339 unsigned char *data;
@@ -653,7 +353,7 @@ static void section_realloc(Section *sec, unsigned long new_size) · 13 unmodified lines
653 353
654/* reserve at least 'size' bytes in section 'sec' from354/* reserve at least 'size' bytes in section 'sec' from
655 sec->data_offset. */355 sec->data_offset. */
656static void *section_ptr_add(Section *sec, unsigned long size)356ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
657{357{
658 unsigned long offset, offset1;358 unsigned long offset, offset1;
659 359
@@ -667,7 +367,7 @@ static void *section_ptr_add(Section *sec, unsigned long size) · 7 unmodified lines
667 367
668/* return a reference to a section, and create it if it does not368/* return a reference to a section, and create it if it does not
669 exists */369 exists */
670Section *find_section(TCCState *s1, const char *name)370ST_FUNC Section *find_section(TCCState *s1, const char *name)
671{371{
672 Section *sec;372 Section *sec;
673 int i;373 int i;
@@ -682,7 +382,7 @@ Section *find_section(TCCState *s1, const char *name) · 8 unmodified lines
682 382
683/* update sym->c so that it points to an external symbol in section383/* update sym->c so that it points to an external symbol in section
684 'section' with value 'value' */384 'section' with value 'value' */
685static void put_extern_sym2(Sym *sym, Section *section, 385ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
686 unsigned long value, unsigned long size,386 unsigned long value, unsigned long size,
687 int can_add_underscore)387 int can_add_underscore)
688{388{
@@ -779,14 +479,14 @@ static void put_extern_sym2(Sym *sym, Section *section, · 90 unmodified lines
779 }479 }
780}480}
781 481
782static void put_extern_sym(Sym *sym, Section *section, 482ST_FUNC void put_extern_sym(Sym *sym, Section *section,
783 unsigned long value, unsigned long size)483 unsigned long value, unsigned long size)
784{484{
785 put_extern_sym2(sym, section, value, size, 1);485 put_extern_sym2(sym, section, value, size, 1);
786}486}
787 487
788/* add a new relocation entry to symbol 'sym' in section 's' */488/* add a new relocation entry to symbol 'sym' in section 's' */
789static void greloc(Section *s, Sym *sym, unsigned long offset, int type)489ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
790{490{
791 int c = 0;491 int c = 0;
792 if (sym) {492 if (sym) {
@@ -798,6 +498,8 @@ static void greloc(Section *s, Sym *sym, unsigned long offset, int type) · 5 unmodified lines
798 put_elf_reloc(symtab_section, s, offset, type, c);498 put_elf_reloc(symtab_section, s, offset, type, c);
799}499}
800 500
501/********************************************************/
502
801static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)503static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
802{504{
803 int len;505 int len;
@@ -813,7 +515,7 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) · 9 unmodified lines
813 va_end(ap);515 va_end(ap);
814}516}
815 517
816void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)518static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
817{519{
818 char buf[2048];520 char buf[2048];
819 BufferedFile **f;521 BufferedFile **f;
@@ -850,7 +552,7 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) · 30 unmodified lines
850 s1->nb_errors++;552 s1->nb_errors++;
851}553}
852 554
853void tcc_set_error_func(TCCState *s, void *error_opaque,555LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
854 void (*error_func)(void *opaque, const char *msg))556 void (*error_func)(void *opaque, const char *msg))
855{557{
856 s->error_opaque = error_opaque;558 s->error_opaque = error_opaque;
@@ -858,7 +560,7 @@ void tcc_set_error_func(TCCState *s, void *error_opaque, · 1 unmodified line
858}560}
859 561
860/* error without aborting current compilation */562/* error without aborting current compilation */
861void error_noabort(const char *fmt, ...)563PUB_FUNC void error_noabort(const char *fmt, ...)
862{564{
863 TCCState *s1 = tcc_state;565 TCCState *s1 = tcc_state;
864 va_list ap;566 va_list ap;
@@ -868,7 +570,7 @@ void error_noabort(const char *fmt, ...) · 3 unmodified lines
868 va_end(ap);570 va_end(ap);
869}571}
870 572
871void error(const char *fmt, ...)573PUB_FUNC void error(const char *fmt, ...)
872{574{
873 TCCState *s1 = tcc_state;575 TCCState *s1 = tcc_state;
874 va_list ap;576 va_list ap;
@@ -885,12 +587,12 @@ void error(const char *fmt, ...) · 10 unmodified lines
885 }587 }
886}588}
887 589
888void expect(const char *msg)590PUB_FUNC void expect(const char *msg)
889{591{
890 error("%s expected", msg);592 error("%s expected", msg);
891}593}
892 594
893void warning(const char *fmt, ...)595PUB_FUNC void warning(const char *fmt, ...)
894{596{
895 TCCState *s1 = tcc_state;597 TCCState *s1 = tcc_state;
896 va_list ap;598 va_list ap;
@@ -903,233 +605,10 @@ void warning(const char *fmt, ...) · 6 unmodified lines
903 va_end(ap);605 va_end(ap);
904}606}
905 607
906void skip(int c)608/********************************************************/
907{
908 if (tok != c)
909 error("'%c' expected", c);
910 next();
911}
912
913static void test_lvalue(void)
914{
915 if (!(vtop->r & VT_LVAL))
916 expect("lvalue");
917}
918
919/* CString handling */
920
921static void cstr_realloc(CString *cstr, int new_size)
922{
923 int size;
924 void *data;
925
926 size = cstr->size_allocated;
927 if (size == 0)
928 size = 8; /* no need to allocate a too small first string */
929 while (size < new_size)
930 size = size * 2;
931 data = tcc_realloc(cstr->data_allocated, size);
932 if (!data)
933 error("memory full");
934 cstr->data_allocated = data;
935 cstr->size_allocated = size;
936 cstr->data = data;
937}
938
939/* add a byte */
940static inline void cstr_ccat(CString *cstr, int ch)
941{
942 int size;
943 size = cstr->size + 1;
944 if (size > cstr->size_allocated)
945 cstr_realloc(cstr, size);
946 ((unsigned char *)cstr->data)[size - 1] = ch;
947 cstr->size = size;
948}
949
950static void cstr_cat(CString *cstr, const char *str)
951{
952 int c;
953 for(;;) {
954 c = *str;
955 if (c == '\0')
956 break;
957 cstr_ccat(cstr, c);
958 str++;
959 }
960}
961
962/* add a wide char */
963static void cstr_wccat(CString *cstr, int ch)
964{
965 int size;
966 size = cstr->size + sizeof(nwchar_t);
967 if (size > cstr->size_allocated)
968 cstr_realloc(cstr, size);
969 *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
970 cstr->size = size;
971}
972
973static void cstr_new(CString *cstr)
974{
975 memset(cstr, 0, sizeof(CString));
976}
977
978/* free string and reset it to NULL */
979static void cstr_free(CString *cstr)
980{
981 tcc_free(cstr->data_allocated);
982 cstr_new(cstr);
983}
984
985#define cstr_reset(cstr) cstr_free(cstr)
986
987/* XXX: unicode ? */
988static void add_char(CString *cstr, int c)
989{
990 if (c == '\'' || c == '\"' || c == '\\') {
991 /* XXX: could be more precise if char or string */
992 cstr_ccat(cstr, '\\');
993 }
994 if (c >= 32 && c <= 126) {
995 cstr_ccat(cstr, c);
996 } else {
997 cstr_ccat(cstr, '\\');
998 if (c == '\n') {
999 cstr_ccat(cstr, 'n');
1000 } else {
1001 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1002 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1003 cstr_ccat(cstr, '0' + (c & 7));
1004 }
1005 }
1006}
1007
1008/* push, without hashing */
1009static Sym *sym_push2(Sym **ps, int v, int t, long c)
1010{
1011 Sym *s;
1012 s = sym_malloc();
1013 s->v = v;
1014 s->type.t = t;
1015 s->type.ref = NULL;
1016#ifdef _WIN64
1017 s->d = NULL;
1018#endif
1019 s->c = c;
1020 s->next = NULL;
1021 /* add in stack */
1022 s->prev = *ps;
1023 *ps = s;
1024 return s;
1025}
1026
1027/* find a symbol and return its associated structure. 's' is the top
1028 of the symbol stack */
1029static Sym *sym_find2(Sym *s, int v)
1030{
1031 while (s) {
1032 if (s->v == v)
1033 return s;
1034 s = s->prev;
1035 }
1036 return NULL;
1037}
1038
1039/* structure lookup */
1040static inline Sym *struct_find(int v)
1041{
1042 v -= TOK_IDENT;
1043 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1044 return NULL;
1045 return table_ident[v]->sym_struct;
1046}
1047
1048/* find an identifier */
1049static inline Sym *sym_find(int v)
1050{
1051 v -= TOK_IDENT;
1052 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1053 return NULL;
1054 return table_ident[v]->sym_identifier;
1055}
1056
1057/* push a given symbol on the symbol stack */
1058static Sym *sym_push(int v, CType *type, int r, int c)
1059{
1060 Sym *s, **ps;
1061 TokenSym *ts;
1062
1063 if (local_stack)
1064 ps = &local_stack;
1065 else
1066 ps = &global_stack;
1067 s = sym_push2(ps, v, type->t, c);
1068 s->type.ref = type->ref;
1069 s->r = r;
1070 /* don't record fields or anonymous symbols */
1071 /* XXX: simplify */
1072 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1073 /* record symbol in token array */
1074 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1075 if (v & SYM_STRUCT)
1076 ps = &ts->sym_struct;
1077 else
1078 ps = &ts->sym_identifier;
1079 s->prev_tok = *ps;
1080 *ps = s;
1081 }
1082 return s;
1083}
1084
1085/* push a global identifier */
1086static Sym *global_identifier_push(int v, int t, int c)
1087{
1088 Sym *s, **ps;
1089 s = sym_push2(&global_stack, v, t, c);
1090 /* don't record anonymous symbol */
1091 if (v < SYM_FIRST_ANOM) {
1092 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1093 /* modify the top most local identifier, so that
1094 sym_identifier will point to 's' when popped */
1095 while (*ps != NULL)
1096 ps = &(*ps)->prev_tok;
1097 s->prev_tok = NULL;
1098 *ps = s;
1099 }
1100 return s;
1101}
1102
1103/* pop symbols until top reaches 'b' */
1104static void sym_pop(Sym **ptop, Sym *b)
1105{
1106 Sym *s, *ss, **ps;
1107 TokenSym *ts;
1108 int v;
1109
1110 s = *ptop;
1111 while(s != b) {
1112 ss = s->prev;
1113 v = s->v;
1114 /* remove symbol in token array */
1115 /* XXX: simplify */
1116 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1117 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1118 if (v & SYM_STRUCT)
1119 ps = &ts->sym_struct;
1120 else
1121 ps = &ts->sym_identifier;
1122 *ps = s->prev_tok;
1123 }
1124 sym_free(s);
1125 s = ss;
1126 }
1127 *ptop = b;
1128}
1129
1130/* I/O layer */609/* I/O layer */
1131 610
1132BufferedFile *tcc_open(TCCState *s1, const char *filename)611ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename)
1133{612{
1134 int fd;613 int fd;
1135 BufferedFile *bf;614 BufferedFile *bf;
@@ -1159,7 +638,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename) · 23 unmodified lines
1159 return bf;638 return bf;
1160}639}
1161 640
1162void tcc_close(BufferedFile *bf)641ST_FUNC void tcc_close(BufferedFile *bf)
1163{642{
1164 total_lines += bf->line_num;643 total_lines += bf->line_num;
1165 close(bf->fd);644 close(bf->fd);
@@ -1272,7 +751,7 @@ static int tcc_compile(TCCState *s1) · 106 unmodified lines
1272 return s1->nb_errors != 0 ? -1 : 0;751 return s1->nb_errors != 0 ? -1 : 0;
1273}752}
1274 753
1275int tcc_compile_string(TCCState *s, const char *str)754LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
1276{755{
1277 BufferedFile bf1, *bf = &bf1;756 BufferedFile bf1, *bf = &bf1;
1278 int ret, len;757 int ret, len;
@@ -1301,7 +780,7 @@ int tcc_compile_string(TCCState *s, const char *str) · 22 unmodified lines
1301}780}
1302 781
1303/* define a preprocessor symbol. A value can also be provided with the '=' operator */782/* define a preprocessor symbol. A value can also be provided with the '=' operator */
1304void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)783LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
1305{784{
1306 BufferedFile bf1, *bf = &bf1;785 BufferedFile bf1, *bf = &bf1;
1307 786
@@ -1331,7 +810,7 @@ void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) · 23 unmodified lines
1331}810}
1332 811
1333/* undefine a preprocessor symbol */812/* undefine a preprocessor symbol */
1334void tcc_undefine_symbol(TCCState *s1, const char *sym)813LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
1335{814{
1336 TokenSym *ts;815 TokenSym *ts;
1337 Sym *s;816 Sym *s;
@@ -1369,7 +848,7 @@ static void tcc_cleanup(void) · 31 unmodified lines
1369 macro_ptr = NULL;848 macro_ptr = NULL;
1370}849}
1371 850
1372TCCState *tcc_new(void)851LIBTCCAPI TCCState *tcc_new(void)
1373{852{
1374 TCCState *s;853 TCCState *s;
1375 char buffer[100];854 char buffer[100];
@@ -1477,6 +956,7 @@ TCCState *tcc_new(void) · 101 unmodified lines
1477 ".dynstrtab", 956 ".dynstrtab",
1478 ".dynhashtab", SHF_PRIVATE);957 ".dynhashtab", SHF_PRIVATE);
1479 s->alacarte_link = 1;958 s->alacarte_link = 1;
959 s->nocommon = 1;
1480 960
1481#ifdef CHAR_IS_UNSIGNED961#ifdef CHAR_IS_UNSIGNED
1482 s->char_is_unsigned = 1;962 s->char_is_unsigned = 1;
@@ -1485,17 +965,15 @@ TCCState *tcc_new(void) · 2 unmodified lines
1485 /* XXX: currently the PE linker is not ready to support that */965 /* XXX: currently the PE linker is not ready to support that */
1486 s->leading_underscore = 1;966 s->leading_underscore = 1;
1487#endif967#endif
1488
1489 if (s->section_align == 0)968 if (s->section_align == 0)
1490 s->section_align = ELF_PAGE_SIZE;969 s->section_align = ELF_PAGE_SIZE;
1491
1492#ifdef TCC_TARGET_I386970#ifdef TCC_TARGET_I386
1493 s->seg_size = 32;971 s->seg_size = 32;
1494#endif972#endif
1495 return s;973 return s;
1496}974}
1497 975
1498void tcc_delete(TCCState *s1)976LIBTCCAPI void tcc_delete(TCCState *s1)
1499{977{
1500 int i;978 int i;
1501 979
@@ -1533,7 +1011,7 @@ void tcc_delete(TCCState *s1) · 31 unmodified lines
1533 tcc_free(s1);1011 tcc_free(s1);
1534}1012}
1535 1013
1536int tcc_add_include_path(TCCState *s1, const char *pathname)1014LIBTCCAPI int tcc_add_include_path(TCCState *s1, const char *pathname)
1537{1015{
1538 char *pathname1;1016 char *pathname1;
1539 1017
@@ -1542,7 +1020,7 @@ int tcc_add_include_path(TCCState *s1, const char *pathname) · 2 unmodified lines
1542 return 0;1020 return 0;
1543}1021}
1544 1022
1545int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)1023LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
1546{1024{
1547 char *pathname1;1025 char *pathname1;
1548 1026
@@ -1668,7 +1146,7 @@ the_end: · 119 unmodified lines
1668 return ret;1146 return ret;
1669}1147}
1670 1148
1671int tcc_add_file(TCCState *s, const char *filename)1149LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
1672{1150{
1673 if (s->output_type == TCC_OUTPUT_PREPROCESS)1151 if (s->output_type == TCC_OUTPUT_PREPROCESS)
1674 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);1152 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) · 1 unmodified line
1676 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);1154 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
1677}1155}
1678 1156
1679int tcc_add_library_path(TCCState *s, const char *pathname)1157LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
1680{1158{
1681 char *pathname1;1159 char *pathname1;
1682 1160
@@ -1687,7 +1165,7 @@ int tcc_add_library_path(TCCState *s, const char *pathname) · 4 unmodified lines
1687 1165
1688/* find and load a dll. Return non zero if not found */1166/* find and load a dll. Return non zero if not found */
1689/* XXX: add '-rpath' option support ? */1167/* XXX: add '-rpath' option support ? */
1690static int tcc_add_dll(TCCState *s, const char *filename, int flags)1168ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
1691{1169{
1692 char buf[1024];1170 char buf[1024];
1693 int i;1171 int i;
@@ -1702,7 +1180,7 @@ static int tcc_add_dll(TCCState *s, const char *filename, int flags) · 8 unmodified lines
1702}1180}
1703 1181
1704/* the library name is the same as the argument of the '-l' option */1182/* the library name is the same as the argument of the '-l' option */
1705int tcc_add_library(TCCState *s, const char *libraryname)1183LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
1706{1184{
1707 char buf[1024];1185 char buf[1024];
1708 int i;1186 int i;
@@ -1728,7 +1206,7 @@ int tcc_add_library(TCCState *s, const char *libraryname) · 19 unmodified lines
1728 return -1;1206 return -1;
1729}1207}
1730 1208
1731int tcc_add_symbol(TCCState *s, const char *name, void *val)1209LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val)
1732{1210{
1733 add_elf_sym(symtab_section, (uplong)val, 0,1211 add_elf_sym(symtab_section, (uplong)val, 0,
1734 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,1212 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
@@ -1736,7 +1214,7 @@ int tcc_add_symbol(TCCState *s, const char *name, void *val) · 1 unmodified line
1736 return 0;1214 return 0;
1737}1215}
1738 1216
1739int tcc_set_output_type(TCCState *s, int output_type)1217LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
1740{1218{
1741 char buf[1024];1219 char buf[1024];
1742 1220
@@ -1825,7 +1303,7 @@ static const FlagDef warning_defs[] = { · 82 unmodified lines
1825 "implicit-function-declaration" },1303 "implicit-function-declaration" },
1826};1304};
1827 1305
1828static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,1306ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
1829 const char *name, int value)1307 const char *name, int value)
1830{1308{
1831 int i;1309 int i;
@@ -1849,9 +1327,8 @@ static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, · 17 unmodified lines
1849 return 0;1327 return 0;
1850}1328}
1851 1329
1852
1853/* set/reset a warning */1330/* set/reset a warning */
1854int tcc_set_warning(TCCState *s, const char *warning_name, int value)1331LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value)
1855{1332{
1856 int i;1333 int i;
1857 const FlagDef *p;1334 const FlagDef *p;
@@ -1876,20 +1353,13 @@ static const FlagDef flag_defs[] = { · 18 unmodified lines
1876};1353};
1877 1354
1878/* set/reset a flag */1355/* set/reset a flag */
1879int tcc_set_flag(TCCState *s, const char *flag_name, int value)1356PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value)
1880{1357{
1881 return set_flag(s, flag_defs, countof(flag_defs),1358 return set_flag(s, flag_defs, countof(flag_defs),
1882 flag_name, value);1359 flag_name, value);
1883}1360}
1884 1361
1885/* set CONFIG_TCCDIR at runtime */1362PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
1886void tcc_set_lib_path(TCCState *s, const char *path)
1887{
1888 tcc_free(s->tcc_lib_path);
1889 s->tcc_lib_path = tcc_strdup(path);
1890}
1891
1892void tcc_print_stats(TCCState *s, int64_t total_time)
1893{1363{
1894 double tt;1364 double tt;
1895 tt = (double)total_time / 1000000.0;1365 tt = (double)total_time / 1000000.0;
@@ -1902,3 +1372,17 @@ void tcc_print_stats(TCCState *s, int64_t total_time) · 6 unmodified lines
1902 tt, (int)(total_lines / tt),1372 tt, (int)(total_lines / tt),
1903 total_bytes / tt / 1000000.0);1373 total_bytes / tt / 1000000.0);
1904}1374}
1375
1376/* set CONFIG_TCCDIR at runtime */
1377LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
1378{
1379 tcc_free(s->tcc_lib_path);
1380 s->tcc_lib_path = tcc_strdup(path);
1381}
1382
1383PUB_FUNC void set_num_callers(int n)
1384{
1385#ifdef CONFIG_TCC_BACKTRACE
1386 num_callers = n;
1387#endif
1388}
tcc.c+16−16
@@ -18,13 +18,25 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#ifdef TCC_USE_LIBTCC21#if defined NOTALLINONE || defined TCC_USE_LIBTCC
22#include "tcc.h"22#include "tcc.h"
23#else23#else
24#include "libtcc.c"24#include "libtcc.c"
25#endif25#endif
26 26
27void help(void)27static char **files;
28static int nb_files, nb_libraries;
29static int multiple_files;
30static int print_search_dirs;
31static int output_type;
32static int reloc_output;
33static const char *outfile;
34static int do_bench = 0;
35
36#define TCC_OPTION_HAS_ARG 0x0001
37#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
38
39static void help(void)
28{40{
29 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"41 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
30 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"42 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
@@ -65,18 +77,6 @@ void help(void) · 34 unmodified lines
65 );77 );
66}78}
67 79
68static char **files;
69static int nb_files, nb_libraries;
70static int multiple_files;
71static int print_search_dirs;
72static int output_type;
73static int reloc_output;
74static const char *outfile;
75static int do_bench = 0;
76
77#define TCC_OPTION_HAS_ARG 0x0001
78#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
79
80typedef struct TCCOption {80typedef struct TCCOption {
81 const char *name;81 const char *name;
82 uint16_t index;82 uint16_t index;
@@ -213,7 +213,7 @@ static int expand_args(char ***pargv, const char *str) · 130 unmodified lines
213 return argc;213 return argc;
214}214}
215 215
216int parse_args(TCCState *s, int argc, char **argv)216static int parse_args(TCCState *s, int argc, char **argv)
217{217{
218 int optind;218 int optind;
219 const TCCOption *popt;219 const TCCOption *popt;
@@ -304,7 +304,7 @@ int parse_args(TCCState *s, int argc, char **argv) · 84 unmodified lines
304 break;304 break;
305#ifdef CONFIG_TCC_BACKTRACE305#ifdef CONFIG_TCC_BACKTRACE
306 case TCC_OPTION_bt:306 case TCC_OPTION_bt:
307 num_callers = atoi(optarg);307 set_num_callers(atoi(optarg));
308 break;308 break;
309#endif309#endif
310#ifdef CONFIG_TCC_BCHECK310#ifdef CONFIG_TCC_BCHECK
tcc.h+406−28
@@ -18,6 +18,9 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#ifndef _TCC_H
22#define _TCC_H
23
21#define _GNU_SOURCE24#define _GNU_SOURCE
22#include "config.h"25#include "config.h"
23 26
@@ -46,6 +49,7 @@ · 22 unmodified lines
46#include <direct.h> /* getcwd */49#include <direct.h> /* getcwd */
47#define inline __inline50#define inline __inline
48#define inp next_inp51#define inp next_inp
52#define dlclose FreeLibrary
49#ifdef _WIN6453#ifdef _WIN64
50#define uplong unsigned long long54#define uplong unsigned long long
51#endif55#endif
@@ -56,6 +60,7 @@ · 4 unmodified lines
56#include <sys/time.h>60#include <sys/time.h>
57#include <sys/ucontext.h>61#include <sys/ucontext.h>
58#include <sys/mman.h>62#include <sys/mman.h>
63#include <dlfcn.h>
59#endif64#endif
60 65
61#endif /* !CONFIG_TCCBOOT */66#endif /* !CONFIG_TCCBOOT */
@@ -766,11 +771,11 @@ enum tcc_token { · 704 unmodified lines
766#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \771#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
767 || defined(__OpenBSD__)772 || defined(__OpenBSD__)
768/* currently incorrect */773/* currently incorrect */
769long double strtold(const char *nptr, char **endptr)774static inline long double strtold(const char *nptr, char **endptr)
770{775{
771 return (long double)strtod(nptr, endptr);776 return (long double)strtod(nptr, endptr);
772}777}
773float strtof(const char *nptr, char **endptr)778static inline float strtof(const char *nptr, char **endptr)
774{779{
775 return (float)strtod(nptr, endptr);780 return (float)strtod(nptr, endptr);
776}781}
@@ -790,38 +795,411 @@ extern long double strtold (const char *__nptr, char **__endptr); · 13 unmodified lines
790#define PATHCMP strcmp795#define PATHCMP strcmp
791#endif796#endif
792 797
793void error(const char *fmt, ...);798/* space exlcuding newline */
794void error_noabort(const char *fmt, ...);799static inline int is_space(int ch)
795void warning(const char *fmt, ...);800{
796 801 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
797void tcc_set_lib_path_w32(TCCState *s);802}
798int tcc_set_flag(TCCState *s, const char *flag_name, int value);
799void tcc_print_stats(TCCState *s, int64_t total_time);
800 803
801void tcc_free(void *ptr);804static inline int isid(int c)
802void *tcc_malloc(unsigned long size);805{
803void *tcc_mallocz(unsigned long size);806 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
804void *tcc_realloc(void *ptr, unsigned long size);807}
805char *tcc_strdup(const char *str);
806 808
807char *tcc_basename(const char *name);809static inline int isnum(int c)
808char *tcc_fileextension (const char *name);810{
809char *pstrcpy(char *buf, int buf_size, const char *s);811 return c >= '0' && c <= '9';
810char *pstrcat(char *buf, int buf_size, const char *s);812}
811void dynarray_add(void ***ptab, int *nb_ptr, void *data);
812void dynarray_reset(void *pp, int *n);
813 813
814/* true if float/double/long double type */814static inline int isoct(int c)
815static inline int is_float(int t)
816{815{
817 int bt;816 return c >= '0' && c <= '7';
818 bt = t & VT_BTYPE;
819 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
820}817}
821 818
822/* space exlcuding newline */819static inline int toup(int c)
823static inline int is_space(int ch)
824{820{
825 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';821 return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
826}822}
827 823
824#define PUB_FUNC
825
826#ifndef NOTALLINONE
827#define ST_INLN static inline
828#define ST_FUNC static
829#define ST_DATA static
830#else
831#define ST_INLN
832#define ST_FUNC
833#define ST_DATA extern
834#endif
835
836/* ------------ libtcc.c ------------ */
837
838/* use GNU C extensions */
839ST_DATA int gnu_ext;
840/* use Tiny C extensions */
841ST_DATA int tcc_ext;
842/* XXX: get rid of this ASAP */
843ST_DATA struct TCCState *tcc_state;
844
845#ifdef CONFIG_TCC_BACKTRACE
846ST_DATA int num_callers;
847ST_DATA const char **rt_bound_error_msg;
848ST_DATA void *rt_prog_main;
849#endif
850
851#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
852#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
853#define AFF_PREPROCESS 0x0004 /* preprocess file */
854
855/* public functions currently used by the tcc main function */
856PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
857PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
858PUB_FUNC char *tcc_basename(const char *name);
859PUB_FUNC char *tcc_fileextension (const char *name);
860PUB_FUNC void tcc_free(void *ptr);
861PUB_FUNC void *tcc_malloc(unsigned long size);
862PUB_FUNC void *tcc_mallocz(unsigned long size);
863PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
864PUB_FUNC char *tcc_strdup(const char *str);
865#define free(p) use_tcc_free(p)
866#define malloc(s) use_tcc_malloc(s)
867#define realloc(p, s) use_tcc_realloc(p, s)
868#undef strdup
869#define strdup(s) use_tcc_strdup(s)
870PUB_FUNC void tcc_memstats(void);
871PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data);
872PUB_FUNC void dynarray_reset(void *pp, int *n);
873PUB_FUNC void error_noabort(const char *fmt, ...);
874PUB_FUNC void error(const char *fmt, ...);
875PUB_FUNC void expect(const char *msg);
876PUB_FUNC void warning(const char *fmt, ...);
877
878/* other utilities */
879ST_INLN void cstr_ccat(CString *cstr, int ch);
880ST_FUNC void cstr_cat(CString *cstr, const char *str);
881ST_FUNC void cstr_wccat(CString *cstr, int ch);
882ST_FUNC void cstr_new(CString *cstr);
883ST_FUNC void cstr_free(CString *cstr);
884ST_FUNC void add_char(CString *cstr, int c);
885#define cstr_reset(cstr) cstr_free(cstr)
886
887ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
888ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
889ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
890ST_FUNC Section *find_section(TCCState *s1, const char *name);
891
892ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore);
893ST_FUNC void put_extern_sym(Sym *sym, Section *section, unsigned long value, unsigned long size);
894ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
895
896ST_INLN void sym_free(Sym *sym);
897ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
898ST_FUNC Sym *sym_find2(Sym *s, int v);
899ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
900ST_FUNC void sym_pop(Sym **ptop, Sym *b);
901ST_INLN Sym *struct_find(int v);
902ST_INLN Sym *sym_find(int v);
903ST_FUNC Sym *global_identifier_push(int v, int t, int c);
904
905ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename);
906ST_FUNC void tcc_close(BufferedFile *bf);
907ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
908PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value);
909PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time);
910PUB_FUNC void set_num_callers(int n);
911
912ST_FUNC int ieee_finite(double d);
913
914/* ------------ tccpp.c ------------ */
915
916ST_DATA struct BufferedFile *file;
917ST_DATA int ch, tok;
918ST_DATA CValue tokc;
919ST_DATA int *macro_ptr;
920ST_DATA int parse_flags;
921ST_DATA int tok_flags;
922ST_DATA CString tokcstr; /* current parsed string, if any */
923
924/* display benchmark infos */
925ST_DATA int total_lines;
926ST_DATA int total_bytes;
927ST_DATA int tok_ident;
928ST_DATA TokenSym **table_ident;
929
930#define TOK_FLAG_BOL 0x0001 /* beginning of line before */
931#define TOK_FLAG_BOF 0x0002 /* beginning of file before */
932#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
933#define TOK_FLAG_EOF 0x0008 /* end of file */
934
935#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
936#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
937#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
938 token. line feed is also
939 returned at eof */
940#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
941#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
942
943ST_FUNC TokenSym *tok_alloc(const char *str, int len);
944ST_FUNC char *get_tok_str(int v, CValue *cv);
945ST_FUNC void save_parse_state(ParseState *s);
946ST_FUNC void restore_parse_state(ParseState *s);
947ST_INLN void tok_str_new(TokenString *s);
948ST_FUNC void tok_str_free(int *str);
949ST_FUNC void tok_str_add(TokenString *s, int t);
950ST_FUNC void tok_str_add_tok(TokenString *s);
951ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
952ST_FUNC void define_undef(Sym *s);
953ST_INLN Sym *define_find(int v);
954ST_FUNC void free_defines(Sym *b);
955ST_FUNC Sym *label_find(int v);
956ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
957ST_FUNC void label_pop(Sym **ptop, Sym *slast);
958ST_FUNC void parse_define(void);
959ST_FUNC void preprocess(int is_bof);
960ST_FUNC void next_nomacro(void);
961ST_FUNC void next(void);
962ST_INLN void unget_tok(int last_tok);
963ST_FUNC void preprocess_init(TCCState *s1);
964ST_FUNC void preprocess_new();
965ST_FUNC int tcc_preprocess(TCCState *s1);
966ST_FUNC void skip(int c);
967
968/* ------------ tccgen.c ------------ */
969
970ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
971ST_DATA Section *cur_text_section; /* current section where function code is generated */
972#ifdef CONFIG_TCC_ASM
973ST_DATA Section *last_text_section; /* to handle .previous asm directive */
974#endif
975#ifdef CONFIG_TCC_BCHECK
976/* bound check related sections */
977ST_DATA Section *bounds_section; /* contains global data bound description */
978ST_DATA Section *lbounds_section; /* contains local data bound description */
979#endif
980/* symbol sections */
981ST_DATA Section *symtab_section, *strtab_section;
982/* debug sections */
983ST_DATA Section *stab_section, *stabstr_section;
984
985#define SYM_POOL_NB (8192 / sizeof(Sym))
986ST_DATA Sym *sym_free_first;
987ST_DATA void **sym_pools;
988ST_DATA int nb_sym_pools;
989
990ST_DATA Sym *global_stack;
991ST_DATA Sym *local_stack;
992ST_DATA Sym *local_label_stack;
993ST_DATA Sym *global_label_stack;
994ST_DATA Sym *define_stack;
995ST_DATA CType char_pointer_type, func_old_type, int_type;
996ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
997ST_DATA int rsym, anon_sym, ind, loc;
998
999ST_DATA int const_wanted; /* true if constant wanted */
1000ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
1001ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
1002ST_DATA CType func_vt; /* current function return type (used by return instruction) */
1003ST_DATA int func_vc;
1004ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
1005ST_DATA char *funcname;
1006
1007ST_INLN int is_float(int t);
1008ST_FUNC void test_lvalue(void);
1009ST_FUNC void swap(int *p, int *q);
1010ST_FUNC void vpushi(int v);
1011ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
1012ST_FUNC void vset(CType *type, int r, int v);
1013ST_FUNC void vswap(void);
1014ST_FUNC void save_reg(int r);
1015ST_FUNC int get_reg(int rc);
1016ST_FUNC void save_regs(int n);
1017ST_FUNC int gv(int rc);
1018ST_FUNC void gv2(int rc1, int rc2);
1019ST_FUNC void vpop(void);
1020ST_FUNC void gen_op(int op);
1021ST_FUNC int type_size(CType *type, int *a);
1022ST_FUNC void mk_pointer(CType *type);
1023ST_FUNC void vstore(void);
1024ST_FUNC void inc(int post, int c);
1025ST_FUNC int lvalue_type(int t);
1026ST_FUNC void indir(void);
1027ST_FUNC void unary(void);
1028ST_FUNC void expr_prod(void);
1029ST_FUNC void expr_sum(void);
1030ST_FUNC void gexpr(void);
1031ST_FUNC int expr_const(void);
1032ST_FUNC void gen_inline_functions(void);
1033ST_FUNC void decl(int l);
1034#ifdef CONFIG_TCC_BCHECK
1035ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
1036#endif
1037
1038/* ------------ tccelf.c ------------ */
1039
1040#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1041
1042typedef struct {
1043 unsigned int n_strx; /* index into string table of name */
1044 unsigned char n_type; /* type of symbol */
1045 unsigned char n_other; /* misc info (usually empty) */
1046 unsigned short n_desc; /* description field */
1047 unsigned int n_value; /* value of symbol */
1048} Stab_Sym;
1049
1050ST_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);
1051
1052ST_FUNC int put_elf_str(Section *s, const char *sym);
1053ST_FUNC int put_elf_sym(Section *s, unsigned long value, unsigned long size, int info, int other, int shndx, const char *name);
1054ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, int info, int other, int sh_num, const char *name);
1055ST_FUNC int find_elf_sym(Section *s, const char *name);
1056ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
1057
1058ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
1059ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
1060ST_FUNC void put_stabn(int type, int other, int desc, int value);
1061ST_FUNC void put_stabd(int type, int other, int desc);
1062
1063ST_FUNC void relocate_common_syms(void);
1064ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
1065ST_FUNC void relocate_section(TCCState *s1, Section *s);
1066
1067ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
1068ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
1069ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
1070ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
1071ST_FUNC void tcc_add_bcheck(TCCState *s1);
1072
1073ST_FUNC void build_got_entries(TCCState *s1);
1074ST_FUNC void tcc_add_runtime(TCCState *s1);
1075
1076#ifndef TCC_TARGET_PE
1077ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
1078ST_FUNC int tcc_load_ldscript(TCCState *s1);
1079ST_FUNC uint8_t *parse_comment(uint8_t *p);
1080ST_FUNC void minp(void);
1081ST_INLN void inp(void);
1082ST_FUNC int handle_eob(void);
1083#endif
1084
1085/* ------------ xxx-gen.c ------------ */
1086
1087ST_FUNC void gsym_addr(int t, int a);
1088ST_FUNC void gsym(int t);
1089ST_FUNC void load(int r, SValue *sv);
1090ST_FUNC void store(int r, SValue *v);
1091ST_FUNC void gfunc_call(int nb_args);
1092ST_FUNC void gfunc_prolog(CType *func_type);
1093ST_FUNC void gfunc_epilog(void);
1094ST_FUNC int gjmp(int t);
1095ST_FUNC void gjmp_addr(int a);
1096ST_FUNC int gtst(int inv, int t);
1097ST_FUNC void gen_opi(int op);
1098ST_FUNC void gen_opf(int op);
1099ST_FUNC void gen_cvt_ftoi(int t);
1100ST_FUNC void gen_cvt_ftof(int t);
1101ST_FUNC void ggoto(void);
1102#ifndef TCC_TARGET_C67
1103ST_FUNC void o(unsigned int c);
1104#endif
1105#ifndef TCC_TARGET_ARM
1106ST_FUNC void gen_cvt_itof(int t);
1107#endif
1108
1109/* ------------ i386-gen.c ------------ */
1110#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1111ST_FUNC void g(int c);
1112ST_FUNC int oad(int c, int s);
1113ST_FUNC void gen_le16(int c);
1114ST_FUNC void gen_le32(int c);
1115ST_FUNC void gen_addr32(int r, Sym *sym, int c);
1116ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
1117#endif
1118
1119#ifdef CONFIG_TCC_BCHECK
1120ST_FUNC void gen_bounded_ptr_add(void);
1121ST_FUNC void gen_bounded_ptr_deref(void);
1122#endif
1123
1124/* ------------ x86_64-gen.c ------------ */
1125#ifdef TCC_TARGET_X86_64
1126ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
1127#endif
1128
1129/* ------------ arm-gen.c ------------ */
1130#ifdef TCC_TARGET_ARM
1131ST_FUNC unsigned long encbranch(int pos,int addr,int fail);
1132ST_FUNC void gen_cvt_itof1(int t);
1133#endif
1134
1135/* ------------ c67-gen.c ------------ */
1136#ifdef TCC_TARGET_C67
1137#endif
1138
1139/* ------------ tcccoff.c ------------ */
1140
1141#ifdef TCC_TARGET_COFF
1142ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
1143#endif
1144
1145/* ------------ tccasm.c ------------ */
1146ST_FUNC void asm_instr(void);
1147ST_FUNC void asm_global_instr(void);
1148
1149#ifdef CONFIG_TCC_ASM
1150ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
1151ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
1152ST_FUNC int asm_int_expr(TCCState *s1);
1153ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
1154/* ------------ i386-asm.c ------------ */
1155ST_FUNC void gen_expr32(ExprValue *pe);
1156ST_FUNC void asm_opcode(TCCState *s1, int opcode);
1157ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
1158ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
1159ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
1160ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
1161#endif
1162/* ------------ tccpe.c -------------- */
1163#ifdef TCC_TARGET_PE
1164ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
1165ST_FUNC int pe_add_dll(struct TCCState *s, const char *libraryname);
1166ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
1167ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv));
1168/* tiny_impdef.c */
1169ST_FUNC char *get_export_names(FILE *fp);
1170#endif
1171
1172/* ------------ tccrun.c ----------------- */
1173#if !defined CONFIG_TCC_STATIC && !defined _WIN32
1174ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
1175#endif
1176
1177/********************************************************/
1178/* include the target specific definitions */
1179
1180#define TARGET_DEFS_ONLY
1181#ifdef TCC_TARGET_I386
1182#include "i386-gen.c"
1183#endif
1184#ifdef TCC_TARGET_X86_64
1185#include "x86_64-gen.c"
1186#endif
1187#ifdef TCC_TARGET_ARM
1188#include "arm-gen.c"
1189#endif
1190#ifdef TCC_TARGET_C67
1191#include "c67-gen.c"
1192#endif
1193#undef TARGET_DEFS_ONLY
1194
1195ST_DATA const int reg_classes[NB_REGS];
1196
1197/********************************************************/
1198#undef ST_DATA
1199#ifndef NOTALLINONE
1200#define ST_DATA static
1201#else
1202#define ST_DATA
1203#endif
1204/********************************************************/
1205#endif /* _TCC_H */
tccasm.c+10−8
@@ -18,7 +18,9 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21static int asm_get_local_label_name(TCCState *s1, unsigned int n)21#include "tcc.h"
22
23ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
22{24{
23 char buf[64];25 char buf[64];
24 TokenSym *ts;26 TokenSym *ts;
@@ -28,7 +30,7 @@ static int asm_get_local_label_name(TCCState *s1, unsigned int n) · 3 unmodified lines
28 return ts->tok;30 return ts->tok;
29}31}
30 32
31static void asm_expr(TCCState *s1, ExprValue *pe);33ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
32 34
33/* We do not use the C expression parser to handle symbols. Maybe the35/* We do not use the C expression parser to handle symbols. Maybe the
34 C expression parser could be tweaked to do so. */36 C expression parser could be tweaked to do so. */
@@ -238,12 +240,12 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) · 203 unmodified lines
238 }240 }
239}241}
240 242
241static void asm_expr(TCCState *s1, ExprValue *pe)243ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
242{244{
243 asm_expr_sum(s1, pe);245 asm_expr_sum(s1, pe);
244}246}
245 247
246static int asm_int_expr(TCCState *s1)248ST_FUNC int asm_int_expr(TCCState *s1)
247{249{
248 ExprValue e;250 ExprValue e;
249 asm_expr(s1, &e);251 asm_expr(s1, &e);
@@ -699,7 +701,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess) · 449 unmodified lines
699}701}
700 702
701/* Assemble the current file */703/* Assemble the current file */
702static int tcc_assemble(TCCState *s1, int do_preprocess)704ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
703{705{
704 Sym *define_start;706 Sym *define_start;
705 int ret;707 int ret;
@@ -765,7 +767,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len) · 59 unmodified lines
765/* find a constraint by its number or id (gcc 3 extended767/* find a constraint by its number or id (gcc 3 extended
766 syntax). return -1 if not found. Return in *pp in char after the768 syntax). return -1 if not found. Return in *pp in char after the
767 constraint */769 constraint */
768static int find_constraint(ASMOperand *operands, int nb_operands, 770ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
769 const char *name, const char **pp)771 const char *name, const char **pp)
770{772{
771 int index;773 int index;
@@ -916,7 +918,7 @@ static void parse_asm_str(CString *astr) · 144 unmodified lines
916}918}
917 919
918/* parse the GCC asm() instruction */920/* parse the GCC asm() instruction */
919static void asm_instr(void)921ST_FUNC void asm_instr(void)
920{922{
921 CString astr, astr1;923 CString astr, astr1;
922 ASMOperand operands[MAX_ASM_OPERANDS];924 ASMOperand operands[MAX_ASM_OPERANDS];
@@ -1017,7 +1019,7 @@ static void asm_instr(void) · 94 unmodified lines
1017 cstr_free(&astr1);1019 cstr_free(&astr1);
1018}1020}
1019 1021
1020static void asm_global_instr(void)1022ST_FUNC void asm_global_instr(void)
1021{1023{
1022 CString astr;1024 CString astr;
1023 1025
tcccoff.c+3−1
@@ -18,6 +18,8 @@ · 17 unmodified lines
18 * License along with this library; if not, write to the Free Software18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */20 */
21
22#include "tcc.h"
21#include "coff.h"23#include "coff.h"
22 24
23#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */25#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
@@ -73,7 +75,7 @@ typedef struct { · 49 unmodified lines
73 unsigned short dummy4;75 unsigned short dummy4;
74} AUXEF;76} AUXEF;
75 77
76int tcc_output_coff(TCCState *s1, FILE *f)78ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
77{79{
78 Section *tcc_sect;80 Section *tcc_sect;
79 SCNHDR *coff_sec;81 SCNHDR *coff_sec;
tccelf.c+27−35
@@ -18,6 +18,8 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#include "tcc.h"
22
21#ifdef TCC_TARGET_X86_6423#ifdef TCC_TARGET_X86_64
22#define ElfW_Rel ElfW(Rela)24#define ElfW_Rel ElfW(Rela)
23#define SHT_RELX SHT_RELA25#define SHT_RELX SHT_RELA
@@ -33,7 +35,7 @@ · 9 unmodified lines
33/* XXX: DLL with PLT would only work with x86-64 for now */35/* XXX: DLL with PLT would only work with x86-64 for now */
34//#define TCC_OUTPUT_DLL_WITH_PLT36//#define TCC_OUTPUT_DLL_WITH_PLT
35 37
36static int put_elf_str(Section *s, const char *sym)38ST_FUNC int put_elf_str(Section *s, const char *sym)
37{39{
38 int offset, len;40 int offset, len;
39 char *ptr;41 char *ptr;
@@ -95,7 +97,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) · 55 unmodified lines
95}97}
96 98
97/* return the symbol number */99/* return the symbol number */
98static int put_elf_sym(Section *s, 100ST_FUNC int put_elf_sym(Section *s,
99 unsigned long value, unsigned long size,101 unsigned long value, unsigned long size,
100 int info, int other, int shndx, const char *name)102 int info, int other, int shndx, const char *name)
101{103{
@@ -145,7 +147,7 @@ static int put_elf_sym(Section *s, · 43 unmodified lines
145 147
146/* find global ELF symbol 'name' and return its index. Return 0 if not148/* find global ELF symbol 'name' and return its index. Return 0 if not
147 found. */149 found. */
148static int find_elf_sym(Section *s, const char *name)150ST_FUNC int find_elf_sym(Section *s, const char *name)
149{151{
150 ElfW(Sym) *sym;152 ElfW(Sym) *sym;
151 Section *hs;153 Section *hs;
@@ -185,20 +187,20 @@ static void *get_elf_sym_addr(TCCState *s, const char *name, int err) · 33 unmodified lines
185}187}
186 188
187/* return elf symbol value */189/* return elf symbol value */
188void *tcc_get_symbol(TCCState *s, const char *name)190LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
189{191{
190 return get_elf_sym_addr(s, name, 0);192 return get_elf_sym_addr(s, name, 0);
191}193}
192 194
193/* return elf symbol value or error */195/* return elf symbol value or error */
194void *tcc_get_symbol_err(TCCState *s, const char *name)196ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name)
195{197{
196 return get_elf_sym_addr(s, name, 1);198 return get_elf_sym_addr(s, name, 1);
197}199}
198 200
199/* add an elf symbol : check if it is already defined and patch201/* add an elf symbol : check if it is already defined and patch
200 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */202 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
201static int add_elf_sym(Section *s, uplong value, unsigned long size,203ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size,
202 int info, int other, int sh_num, const char *name)204 int info, int other, int sh_num, const char *name)
203{205{
204 ElfW(Sym) *esym;206 ElfW(Sym) *esym;
@@ -272,7 +274,7 @@ static int add_elf_sym(Section *s, uplong value, unsigned long size, · 67 unmodified lines
272}274}
273 275
274/* put relocation */276/* put relocation */
275static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,277ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
276 int type, int symbol)278 int type, int symbol)
277{279{
278 char buf[256];280 char buf[256];
@@ -301,15 +303,7 @@ static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, · 22 unmodified lines
301 303
302/* put stab debug information */304/* put stab debug information */
303 305
304typedef struct {306ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
305 unsigned int n_strx; /* index into string table of name */
306 unsigned char n_type; /* type of symbol */
307 unsigned char n_other; /* misc info (usually empty) */
308 unsigned short n_desc; /* description field */
309 unsigned int n_value; /* value of symbol */
310} Stab_Sym;
311
312static void put_stabs(const char *str, int type, int other, int desc,
313 unsigned long value)307 unsigned long value)
314{308{
315 Stab_Sym *sym;309 Stab_Sym *sym;
@@ -326,7 +320,7 @@ static void put_stabs(const char *str, int type, int other, int desc, · 10 unmodified lines
326 sym->n_value = value;320 sym->n_value = value;
327}321}
328 322
329static void put_stabs_r(const char *str, int type, int other, int desc, 323ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
330 unsigned long value, Section *sec, int sym_index)324 unsigned long value, Section *sec, int sym_index)
331{325{
332 put_stabs(str, type, other, desc, value);326 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, · 2 unmodified lines
335 R_DATA_32, sym_index);329 R_DATA_32, sym_index);
336}330}
337 331
338static void put_stabn(int type, int other, int desc, int value)332ST_FUNC void put_stabn(int type, int other, int desc, int value)
339{333{
340 put_stabs(NULL, type, other, desc, value);334 put_stabs(NULL, type, other, desc, value);
341}335}
342 336
343static void put_stabd(int type, int other, int desc)337ST_FUNC void put_stabd(int type, int other, int desc)
344{338{
345 put_stabs(NULL, type, other, desc, 0);339 put_stabs(NULL, type, other, desc, 0);
346}340}
@@ -410,7 +404,7 @@ static void sort_syms(TCCState *s1, Section *s) · 63 unmodified lines
410}404}
411 405
412/* relocate common symbols in the .bss section */406/* relocate common symbols in the .bss section */
413static void relocate_common_syms(void)407ST_FUNC void relocate_common_syms(void)
414{408{
415 ElfW(Sym) *sym, *sym_end;409 ElfW(Sym) *sym, *sym_end;
416 unsigned long offset, align;410 unsigned long offset, align;
@@ -434,7 +428,7 @@ static void relocate_common_syms(void) · 17 unmodified lines
434 428
435/* relocate symbol table, resolve undefined symbols if do_resolve is429/* relocate symbol table, resolve undefined symbols if do_resolve is
436 true and output error if undefined symbol. */430 true and output error if undefined symbol. */
437static void relocate_syms(TCCState *s1, int do_resolve)431ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
438{432{
439 ElfW(Sym) *sym, *esym, *sym_end;433 ElfW(Sym) *sym, *esym, *sym_end;
440 int sym_bind, sh_num, sym_index;434 int sym_bind, sh_num, sym_index;
@@ -513,7 +507,7 @@ static unsigned long add_got_table(TCCState *s1, unsigned long val) · 72 unmodified lines
513#endif507#endif
514 508
515/* relocate a given section (CPU dependent) */509/* relocate a given section (CPU dependent) */
516static void relocate_section(TCCState *s1, Section *s)510ST_FUNC void relocate_section(TCCState *s1, Section *s)
517{511{
518 Section *sr;512 Section *sr;
519 ElfW_Rel *rel, *rel_end, *qrel;513 ElfW_Rel *rel, *rel_end, *qrel;
@@ -1012,7 +1006,7 @@ static void put_got_entry(TCCState *s1, · 492 unmodified lines
1012}1006}
1013 1007
1014/* build GOT and PLT entries */1008/* build GOT and PLT entries */
1015static void build_got_entries(TCCState *s1)1009ST_FUNC void build_got_entries(TCCState *s1)
1016{1010{
1017 Section *s, *symtab;1011 Section *s, *symtab;
1018 ElfW_Rel *rel, *rel_end;1012 ElfW_Rel *rel, *rel_end;
@@ -1120,7 +1114,7 @@ static void build_got_entries(TCCState *s1) · 101 unmodified lines
1120 }1114 }
1121}1115}
1122 1116
1123static Section *new_symtab(TCCState *s1,1117ST_FUNC Section *new_symtab(TCCState *s1,
1124 const char *symtab_name, int sh_type, int sh_flags,1118 const char *symtab_name, int sh_type, int sh_flags,
1125 const char *strtab_name, 1119 const char *strtab_name,
1126 const char *hash_name, int hash_sh_flags)1120 const char *hash_name, int hash_sh_flags)
@@ -1186,7 +1180,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) · 59 unmodified lines
1186 s->sh_num, sym_end);1180 s->sh_num, sym_end);
1187}1181}
1188 1182
1189static void tcc_add_bcheck(TCCState *s1)1183ST_FUNC void tcc_add_bcheck(TCCState *s1)
1190{1184{
1191#ifdef CONFIG_TCC_BCHECK1185#ifdef CONFIG_TCC_BCHECK
1192 unsigned long *ptr;1186 unsigned long *ptr;
@@ -1227,7 +1221,7 @@ static void tcc_add_bcheck(TCCState *s1) · 34 unmodified lines
1227}1221}
1228 1222
1229/* add tcc runtime libraries */1223/* add tcc runtime libraries */
1230static void tcc_add_runtime(TCCState *s1)1224ST_FUNC void tcc_add_runtime(TCCState *s1)
1231{1225{
1232 tcc_add_bcheck(s1);1226 tcc_add_bcheck(s1);
1233 1227
@@ -1252,7 +1246,7 @@ static void tcc_add_runtime(TCCState *s1) · 18 unmodified lines
1252/* add various standard linker symbols (must be done after the1246/* add various standard linker symbols (must be done after the
1253 sections are filled (for example after allocating common1247 sections are filled (for example after allocating common
1254 symbols)) */1248 symbols)) */
1255static void tcc_add_linker_symbols(TCCState *s1)1249ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1256{1250{
1257 char buf[1024];1251 char buf[1024];
1258 int i;1252 int i;
@@ -1371,7 +1365,7 @@ void patch_dynsym_undef(TCCState *s1, Section *s) · 112 unmodified lines
1371 1365
1372/* output an ELF file */1366/* output an ELF file */
1373/* XXX: suppress unneeded sections */1367/* XXX: suppress unneeded sections */
1374int elf_output_file(TCCState *s1, const char *filename)1368static int elf_output_file(TCCState *s1, const char *filename)
1375{1369{
1376 ElfW(Ehdr) ehdr;1370 ElfW(Ehdr) ehdr;
1377 FILE *f;1371 FILE *f;
@@ -2110,7 +2104,7 @@ int elf_output_file(TCCState *s1, const char *filename) · 732 unmodified lines
2110 return ret;2104 return ret;
2111}2105}
2112 2106
2113int tcc_output_file(TCCState *s, const char *filename)2107LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2114{2108{
2115 int ret;2109 int ret;
2116#ifdef TCC_TARGET_PE2110#ifdef TCC_TARGET_PE
@@ -2143,7 +2137,7 @@ typedef struct SectionMergeInfo { · 26 unmodified lines
2143 2137
2144/* load an object file and merge it with current files */2138/* load an object file and merge it with current files */
2145/* XXX: handle correctly stab (debug) info */2139/* XXX: handle correctly stab (debug) info */
2146static int tcc_load_object_file(TCCState *s1, 2140ST_FUNC int tcc_load_object_file(TCCState *s1,
2147 int fd, unsigned long file_offset)2141 int fd, unsigned long file_offset)
2148{ 2142{
2149 ElfW(Ehdr) ehdr;2143 ElfW(Ehdr) ehdr;
@@ -2412,8 +2406,6 @@ static int tcc_load_object_file(TCCState *s1, · 262 unmodified lines
2412 return ret;2406 return ret;
2413}2407}
2414 2408
2415#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2416
2417typedef struct ArchiveHeader {2409typedef struct ArchiveHeader {
2418 char ar_name[16]; /* name of this member */2410 char ar_name[16]; /* name of this member */
2419 char ar_date[12]; /* file mtime */2411 char ar_date[12]; /* file mtime */
@@ -2474,7 +2466,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) · 54 unmodified lines
2474}2466}
2475 2467
2476/* load a '.a' file */2468/* load a '.a' file */
2477static int tcc_load_archive(TCCState *s1, int fd)2469ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2478{2470{
2479 ArchiveHeader hdr;2471 ArchiveHeader hdr;
2480 char ar_size[11];2472 char ar_size[11];
@@ -2529,7 +2521,7 @@ static int tcc_load_archive(TCCState *s1, int fd) · 48 unmodified lines
2529/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL2521/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2530 is referenced by the user (so it should be added as DT_NEEDED in2522 is referenced by the user (so it should be added as DT_NEEDED in
2531 the generated ELF file) */2523 the generated ELF file) */
2532static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)2524ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2533{ 2525{
2534 ElfW(Ehdr) ehdr;2526 ElfW(Ehdr) ehdr;
2535 ElfW(Shdr) *shdr, *sh, *sh1;2527 ElfW(Shdr) *shdr, *sh, *sh1;
@@ -2802,7 +2794,7 @@ static int ld_add_file_list(TCCState *s1, int as_needed) · 266 unmodified lines
2802 2794
2803/* interpret a subset of GNU ldscripts to handle the dummy libc.so2795/* interpret a subset of GNU ldscripts to handle the dummy libc.so
2804 files */2796 files */
2805static int tcc_load_ldscript(TCCState *s1)2797ST_FUNC int tcc_load_ldscript(TCCState *s1)
2806{2798{
2807 char cmd[64];2799 char cmd[64];
2808 char filename[1024];2800 char filename[1024];
tccgen.c+290−52
@@ -18,7 +18,244 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21void swap(int *p, int *q)21#include "tcc.h"
22
23/********************************************************/
24/* global variables */
25
26/* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
30*/
31ST_DATA int rsym, anon_sym, ind, loc;
32
33ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34ST_DATA Section *cur_text_section; /* current section where function code is generated */
35#ifdef CONFIG_TCC_ASM
36ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37#endif
38#ifdef CONFIG_TCC_BCHECK
39/* bound check related sections */
40ST_DATA Section *bounds_section; /* contains global data bound description */
41ST_DATA Section *lbounds_section; /* contains local data bound description */
42#endif
43/* symbol sections */
44ST_DATA Section *symtab_section, *strtab_section;
45/* debug sections */
46ST_DATA Section *stab_section, *stabstr_section;
47ST_DATA Sym *sym_free_first;
48ST_DATA void **sym_pools;
49ST_DATA int nb_sym_pools;
50
51ST_DATA Sym *global_stack;
52ST_DATA Sym *local_stack;
53ST_DATA Sym *define_stack;
54ST_DATA Sym *global_label_stack;
55ST_DATA Sym *local_label_stack;
56
57ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
58
59ST_DATA int const_wanted; /* true if constant wanted */
60ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
61ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
62ST_DATA CType func_vt; /* current function return type (used by return instruction) */
63ST_DATA int func_vc;
64ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
65ST_DATA char *funcname;
66
67ST_DATA CType char_pointer_type, func_old_type, int_type;
68
69/* ------------------------------------------------------------------------- */
70static void gen_cast(CType *type);
71static inline CType *pointed_type(CType *type);
72static int is_compatible_types(CType *type1, CType *type2);
73static int parse_btype(CType *type, AttributeDef *ad);
74static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
75static void parse_expr_type(CType *type);
76static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
77static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
78static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
79static void expr_eq(void);
80static void unary_type(CType *type);
81static int is_compatible_parameter_types(CType *type1, CType *type2);
82static void expr_type(CType *type);
83
84ST_INLN int is_float(int t)
85{
86 int bt;
87 bt = t & VT_BTYPE;
88 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
89}
90
91ST_FUNC void test_lvalue(void)
92{
93 if (!(vtop->r & VT_LVAL))
94 expect("lvalue");
95}
96
97/* ------------------------------------------------------------------------- */
98/* symbol allocator */
99static Sym *__sym_malloc(void)
100{
101 Sym *sym_pool, *sym, *last_sym;
102 int i;
103
104 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
105 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
106
107 last_sym = sym_free_first;
108 sym = sym_pool;
109 for(i = 0; i < SYM_POOL_NB; i++) {
110 sym->next = last_sym;
111 last_sym = sym;
112 sym++;
113 }
114 sym_free_first = last_sym;
115 return last_sym;
116}
117
118static inline Sym *sym_malloc(void)
119{
120 Sym *sym;
121 sym = sym_free_first;
122 if (!sym)
123 sym = __sym_malloc();
124 sym_free_first = sym->next;
125 return sym;
126}
127
128ST_INLN void sym_free(Sym *sym)
129{
130 sym->next = sym_free_first;
131 sym_free_first = sym;
132}
133
134/* push, without hashing */
135ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
136{
137 Sym *s;
138 s = sym_malloc();
139 s->v = v;
140 s->type.t = t;
141 s->type.ref = NULL;
142#ifdef _WIN64
143 s->d = NULL;
144#endif
145 s->c = c;
146 s->next = NULL;
147 /* add in stack */
148 s->prev = *ps;
149 *ps = s;
150 return s;
151}
152
153/* find a symbol and return its associated structure. 's' is the top
154 of the symbol stack */
155ST_FUNC Sym *sym_find2(Sym *s, int v)
156{
157 while (s) {
158 if (s->v == v)
159 return s;
160 s = s->prev;
161 }
162 return NULL;
163}
164
165/* structure lookup */
166ST_INLN Sym *struct_find(int v)
167{
168 v -= TOK_IDENT;
169 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
170 return NULL;
171 return table_ident[v]->sym_struct;
172}
173
174/* find an identifier */
175ST_INLN Sym *sym_find(int v)
176{
177 v -= TOK_IDENT;
178 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
179 return NULL;
180 return table_ident[v]->sym_identifier;
181}
182
183/* push a given symbol on the symbol stack */
184ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
185{
186 Sym *s, **ps;
187 TokenSym *ts;
188
189 if (local_stack)
190 ps = &local_stack;
191 else
192 ps = &global_stack;
193 s = sym_push2(ps, v, type->t, c);
194 s->type.ref = type->ref;
195 s->r = r;
196 /* don't record fields or anonymous symbols */
197 /* XXX: simplify */
198 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
199 /* record symbol in token array */
200 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
201 if (v & SYM_STRUCT)
202 ps = &ts->sym_struct;
203 else
204 ps = &ts->sym_identifier;
205 s->prev_tok = *ps;
206 *ps = s;
207 }
208 return s;
209}
210
211/* push a global identifier */
212ST_FUNC Sym *global_identifier_push(int v, int t, int c)
213{
214 Sym *s, **ps;
215 s = sym_push2(&global_stack, v, t, c);
216 /* don't record anonymous symbol */
217 if (v < SYM_FIRST_ANOM) {
218 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
219 /* modify the top most local identifier, so that
220 sym_identifier will point to 's' when popped */
221 while (*ps != NULL)
222 ps = &(*ps)->prev_tok;
223 s->prev_tok = NULL;
224 *ps = s;
225 }
226 return s;
227}
228
229/* pop symbols until top reaches 'b' */
230ST_FUNC void sym_pop(Sym **ptop, Sym *b)
231{
232 Sym *s, *ss, **ps;
233 TokenSym *ts;
234 int v;
235
236 s = *ptop;
237 while(s != b) {
238 ss = s->prev;
239 v = s->v;
240 /* remove symbol in token array */
241 /* XXX: simplify */
242 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
243 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
244 if (v & SYM_STRUCT)
245 ps = &ts->sym_struct;
246 else
247 ps = &ts->sym_identifier;
248 *ps = s->prev_tok;
249 }
250 sym_free(s);
251 s = ss;
252 }
253 *ptop = b;
254}
255
256/* ------------------------------------------------------------------------- */
257
258ST_FUNC void swap(int *p, int *q)
22{259{
23 int t;260 int t;
24 t = *p;261 t = *p;
@@ -26,7 +263,7 @@ void swap(int *p, int *q) · 1 unmodified line
26 *q = t;263 *q = t;
27}264}
28 265
29void vsetc(CType *type, int r, CValue *vc)266static void vsetc(CType *type, int r, CValue *vc)
30{267{
31 int v;268 int v;
32 269
@@ -48,7 +285,7 @@ void vsetc(CType *type, int r, CValue *vc) · 15 unmodified lines
48}285}
49 286
50/* push integer constant */287/* push integer constant */
51void vpushi(int v)288ST_FUNC void vpushi(int v)
52{289{
53 CValue cval;290 CValue cval;
54 cval.i = v;291 cval.i = v;
@@ -56,7 +293,7 @@ void vpushi(int v) · 1 unmodified line
56}293}
57 294
58/* push long long constant */295/* push long long constant */
59void vpushll(long long v)296static void vpushll(long long v)
60{297{
61 CValue cval;298 CValue cval;
62 CType ctype;299 CType ctype;
@@ -67,8 +304,7 @@ void vpushll(long long v) · 4 unmodified lines
67}304}
68 305
69/* Return a static symbol pointing to a section */306/* Return a static symbol pointing to a section */
70static Sym *get_sym_ref(CType *type, Section *sec, 307ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
71 unsigned long offset, unsigned long size)
72{308{
73 int v;309 int v;
74 Sym *sym;310 Sym *sym;
@@ -92,7 +328,7 @@ static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned · 17 unmodified lines
92}328}
93 329
94/* define a new external reference to a symbol 'v' of type 'u' */330/* define a new external reference to a symbol 'v' of type 'u' */
95static Sym *external_global_sym(int v, CType *type, int r)331ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
96{332{
97 Sym *s;333 Sym *s;
98 334
@@ -139,7 +375,7 @@ static void vpush_global_sym(CType *type, int v) · 40 unmodified lines
139 vtop->sym = sym;375 vtop->sym = sym;
140}376}
141 377
142void vset(CType *type, int r, int v)378ST_FUNC void vset(CType *type, int r, int v)
143{379{
144 CValue cval;380 CValue cval;
145 381
@@ -147,7 +383,7 @@ void vset(CType *type, int r, int v) · 1 unmodified line
147 vsetc(type, r, &cval);383 vsetc(type, r, &cval);
148}384}
149 385
150void vseti(int r, int v)386static void vseti(int r, int v)
151{387{
152 CType type;388 CType type;
153 type.t = VT_INT;389 type.t = VT_INT;
@@ -155,7 +391,7 @@ void vseti(int r, int v) · 1 unmodified line
155 vset(&type, r, v);391 vset(&type, r, v);
156}392}
157 393
158void vswap(void)394ST_FUNC void vswap(void)
159{395{
160 SValue tmp;396 SValue tmp;
161 397
@@ -164,7 +400,7 @@ void vswap(void) · 2 unmodified lines
164 vtop[-1] = tmp;400 vtop[-1] = tmp;
165}401}
166 402
167void vpushv(SValue *v)403static void vpushv(SValue *v)
168{404{
169 if (vtop >= vstack + (VSTACK_SIZE - 1))405 if (vtop >= vstack + (VSTACK_SIZE - 1))
170 error("memory full");406 error("memory full");
@@ -172,13 +408,13 @@ void vpushv(SValue *v) · 1 unmodified line
172 *vtop = *v;408 *vtop = *v;
173}409}
174 410
175void vdup(void)411static void vdup(void)
176{412{
177 vpushv(vtop);413 vpushv(vtop);
178}414}
179 415
180/* save r to the memory stack, and mark it as being free */416/* save r to the memory stack, and mark it as being free */
181void save_reg(int r)417ST_FUNC void save_reg(int r)
182{418{
183 int l, saved, size, align;419 int l, saved, size, align;
184 SValue *p, sv;420 SValue *p, sv;
@@ -240,9 +476,10 @@ void save_reg(int r) · 55 unmodified lines
240 }476 }
241}477}
242 478
479#ifdef TCC_TARGET_ARM
243/* find a register of class 'rc2' with at most one reference on stack.480/* find a register of class 'rc2' with at most one reference on stack.
244 * If none, call get_reg(rc) */481 * If none, call get_reg(rc) */
245int get_reg_ex(int rc, int rc2) 482ST_FUNC int get_reg_ex(int rc, int rc2)
246{483{
247 int r;484 int r;
248 SValue *p;485 SValue *p;
@@ -262,9 +499,10 @@ int get_reg_ex(int rc, int rc2) · 13 unmodified lines
262 }499 }
263 return get_reg(rc);500 return get_reg(rc);
264}501}
502#endif
265 503
266/* find a free register of class 'rc'. If none, save one register */504/* find a free register of class 'rc'. If none, save one register */
267int get_reg(int rc)505ST_FUNC int get_reg(int rc)
268{506{
269 int r;507 int r;
270 SValue *p;508 SValue *p;
@@ -302,7 +540,7 @@ int get_reg(int rc) · 31 unmodified lines
302}540}
303 541
304/* save registers up to (vtop - n) stack entry */542/* save registers up to (vtop - n) stack entry */
305void save_regs(int n)543ST_FUNC void save_regs(int n)
306{544{
307 int r;545 int r;
308 SValue *p, *p1;546 SValue *p, *p1;
@@ -317,7 +555,7 @@ void save_regs(int n) · 8 unmodified lines
317 555
318/* move register 's' to 'r', and flush previous value of r to memory556/* move register 's' to 'r', and flush previous value of r to memory
319 if needed */557 if needed */
320void move_reg(int r, int s)558static void move_reg(int r, int s)
321{559{
322 SValue sv;560 SValue sv;
323 561
@@ -331,7 +569,7 @@ void move_reg(int r, int s) · 7 unmodified lines
331}569}
332 570
333/* get address of vtop (vtop MUST BE an lvalue) */571/* get address of vtop (vtop MUST BE an lvalue) */
334void gaddrof(void)572static void gaddrof(void)
335{573{
336 vtop->r &= ~VT_LVAL;574 vtop->r &= ~VT_LVAL;
337 /* tricky: if saved lvalue, then we can go back to lvalue */575 /* tricky: if saved lvalue, then we can go back to lvalue */
@@ -341,7 +579,7 @@ void gaddrof(void) · 3 unmodified lines
341 579
342#ifdef CONFIG_TCC_BCHECK580#ifdef CONFIG_TCC_BCHECK
343/* generate lvalue bound code */581/* generate lvalue bound code */
344void gbound(void)582static void gbound(void)
345{583{
346 int lval_type;584 int lval_type;
347 CType type1;585 CType type1;
@@ -370,7 +608,7 @@ void gbound(void) · 22 unmodified lines
370/* store vtop a register belonging to class 'rc'. lvalues are608/* store vtop a register belonging to class 'rc'. lvalues are
371 converted to values. Cannot be used if cannot be converted to609 converted to values. Cannot be used if cannot be converted to
372 register value (such as structures). */610 register value (such as structures). */
373int gv(int rc)611ST_FUNC int gv(int rc)
374{612{
375 int r, rc2, bit_pos, bit_size, size, align, i;613 int r, rc2, bit_pos, bit_size, size, align, i;
376 614
@@ -537,7 +775,7 @@ int gv(int rc) · 160 unmodified lines
537}775}
538 776
539/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */777/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
540void gv2(int rc1, int rc2)778ST_FUNC void gv2(int rc1, int rc2)
541{779{
542 int v;780 int v;
543 781
@@ -569,7 +807,7 @@ void gv2(int rc1, int rc2) · 25 unmodified lines
569}807}
570 808
571/* wrapper around RC_FRET to return a register by type */809/* wrapper around RC_FRET to return a register by type */
572int rc_fret(int t)810static int rc_fret(int t)
573{811{
574#ifdef TCC_TARGET_X86_64812#ifdef TCC_TARGET_X86_64
575 if (t == VT_LDOUBLE) {813 if (t == VT_LDOUBLE) {
@@ -580,7 +818,7 @@ int rc_fret(int t) · 4 unmodified lines
580}818}
581 819
582/* wrapper around REG_FRET to return a register by type */820/* wrapper around REG_FRET to return a register by type */
583int reg_fret(int t)821static int reg_fret(int t)
584{822{
585#ifdef TCC_TARGET_X86_64823#ifdef TCC_TARGET_X86_64
586 if (t == VT_LDOUBLE) {824 if (t == VT_LDOUBLE) {
@@ -591,7 +829,7 @@ int reg_fret(int t) · 4 unmodified lines
591}829}
592 830
593/* expand long long on stack in two int registers */831/* expand long long on stack in two int registers */
594void lexpand(void)832static void lexpand(void)
595{833{
596 int u;834 int u;
597 835
@@ -607,7 +845,7 @@ void lexpand(void) · 9 unmodified lines
607 845
608#ifdef TCC_TARGET_ARM846#ifdef TCC_TARGET_ARM
609/* expand long long on stack */847/* expand long long on stack */
610void lexpand_nr(void)848ST_FUNC void lexpand_nr(void)
611{849{
612 int u,v;850 int u,v;
613 851
@@ -634,7 +872,7 @@ void lexpand_nr(void) · 20 unmodified lines
634#endif872#endif
635 873
636/* build a long long from two ints */874/* build a long long from two ints */
637void lbuild(int t)875static void lbuild(int t)
638{876{
639 gv2(RC_INT, RC_INT);877 gv2(RC_INT, RC_INT);
640 vtop[-1].r2 = vtop[0].r;878 vtop[-1].r2 = vtop[0].r;
@@ -645,7 +883,7 @@ void lbuild(int t) · 4 unmodified lines
645/* rotate n first stack elements to the bottom 883/* rotate n first stack elements to the bottom
646 I1 ... In -> I2 ... In I1 [top is right]884 I1 ... In -> I2 ... In I1 [top is right]
647*/885*/
648void vrotb(int n)886static void vrotb(int n)
649{887{
650 int i;888 int i;
651 SValue tmp;889 SValue tmp;
@@ -659,7 +897,7 @@ void vrotb(int n) · 7 unmodified lines
659/* rotate n first stack elements to the top 897/* rotate n first stack elements to the top
660 I1 ... In -> In I1 ... I(n-1) [top is right]898 I1 ... In -> In I1 ... I(n-1) [top is right]
661 */899 */
662void vrott(int n)900static void vrott(int n)
663{901{
664 int i;902 int i;
665 SValue tmp;903 SValue tmp;
@@ -687,7 +925,7 @@ void vnrott(int n) · 21 unmodified lines
687#endif925#endif
688 926
689/* pop stack value */927/* pop stack value */
690void vpop(void)928ST_FUNC void vpop(void)
691{929{
692 int v;930 int v;
693 v = vtop->r & VT_VALMASK;931 v = vtop->r & VT_VALMASK;
@@ -706,7 +944,7 @@ void vpop(void) · 12 unmodified lines
706 944
707/* convert stack entry to register and duplicate its value in another945/* convert stack entry to register and duplicate its value in another
708 register */946 register */
709void gv_dup(void)947static void gv_dup(void)
710{948{
711 int rc, t, r, r1;949 int rc, t, r, r1;
712 SValue sv;950 SValue sv;
@@ -753,7 +991,7 @@ void gv_dup(void) · 40 unmodified lines
753 991
754#ifndef TCC_TARGET_X86_64992#ifndef TCC_TARGET_X86_64
755/* generate CPU independent (unsigned) long long operations */993/* generate CPU independent (unsigned) long long operations */
756void gen_opl(int op)994static void gen_opl(int op)
757{995{
758 int t, a, b, op1, c, i;996 int t, a, b, op1, c, i;
759 int func;997 int func;
@@ -990,7 +1228,7 @@ void gen_opl(int op) · 230 unmodified lines
990 1228
991/* handle integer constant optimizations and various machine1229/* handle integer constant optimizations and various machine
992 independent opt */1230 independent opt */
993void gen_opic(int op)1231static void gen_opic(int op)
994{1232{
995 int c1, c2, t1, t2, n;1233 int c1, c2, t1, t2, n;
996 SValue *v1, *v2;1234 SValue *v1, *v2;
@@ -1130,7 +1368,7 @@ void gen_opic(int op) · 133 unmodified lines
1130}1368}
1131 1369
1132/* generate a floating point operation with constant propagation */1370/* generate a floating point operation with constant propagation */
1133void gen_opif(int op)1371static void gen_opif(int op)
1134{1372{
1135 int c1, c2;1373 int c1, c2;
1136 SValue *v1, *v2;1374 SValue *v1, *v2;
@@ -1262,7 +1500,7 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) · 125 unmodified lines
1262}1500}
1263 1501
1264/* generic gen_op: handles types problems */1502/* generic gen_op: handles types problems */
1265void gen_op(int op)1503ST_FUNC void gen_op(int op)
1266{1504{
1267 int u, t1, t2, bt1, bt2, t;1505 int u, t1, t2, bt1, bt2, t;
1268 CType type1;1506 CType type1;
@@ -1411,7 +1649,7 @@ void gen_op(int op) · 142 unmodified lines
1411 1649
1412#ifndef TCC_TARGET_ARM1650#ifndef TCC_TARGET_ARM
1413/* generic itof for unsigned long long case */1651/* generic itof for unsigned long long case */
1414void gen_cvt_itof1(int t)1652static void gen_cvt_itof1(int t)
1415{1653{
1416 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 1654 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1417 (VT_LLONG | VT_UNSIGNED)) {1655 (VT_LLONG | VT_UNSIGNED)) {
@@ -1435,7 +1673,7 @@ void gen_cvt_itof1(int t) · 17 unmodified lines
1435#endif1673#endif
1436 1674
1437/* generic ftoi for unsigned long long case */1675/* generic ftoi for unsigned long long case */
1438void gen_cvt_ftoi1(int t)1676static void gen_cvt_ftoi1(int t)
1439{1677{
1440 int st;1678 int st;
1441 1679
@@ -1461,7 +1699,7 @@ void gen_cvt_ftoi1(int t) · 19 unmodified lines
1461}1699}
1462 1700
1463/* force char or short cast */1701/* force char or short cast */
1464void force_charshort_cast(int t)1702static void force_charshort_cast(int t)
1465{1703{
1466 int bits, dbt;1704 int bits, dbt;
1467 dbt = t & VT_BTYPE;1705 dbt = t & VT_BTYPE;
@@ -1672,7 +1910,7 @@ static void gen_cast(CType *type) · 204 unmodified lines
1672}1910}
1673 1911
1674/* return type size. Put alignment at 'a' */1912/* return type size. Put alignment at 'a' */
1675static int type_size(CType *type, int *a)1913ST_FUNC int type_size(CType *type, int *a)
1676{1914{
1677 Sym *s;1915 Sym *s;
1678 int bt;1916 int bt;
@@ -1738,7 +1976,7 @@ static inline CType *pointed_type(CType *type) · 59 unmodified lines
1738}1976}
1739 1977
1740/* modify type so that its it is a pointer to type. */1978/* modify type so that its it is a pointer to type. */
1741static void mk_pointer(CType *type)1979ST_FUNC void mk_pointer(CType *type)
1742{1980{
1743 Sym *s;1981 Sym *s;
1744 s = sym_push(SYM_FIELD, type, 0, -1);1982 s = sym_push(SYM_FIELD, type, 0, -1);
@@ -1829,7 +2067,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2) · 84 unmodified lines
1829 printed in the type */2067 printed in the type */
1830/* XXX: union */2068/* XXX: union */
1831/* XXX: add array and function pointers */2069/* XXX: add array and function pointers */
1832void type_to_str(char *buf, int buf_size, 2070static void type_to_str(char *buf, int buf_size,
1833 CType *type, const char *varstr)2071 CType *type, const char *varstr)
1834{2072{
1835 int bt, v, t;2073 int bt, v, t;
@@ -2000,7 +2238,7 @@ static void gen_assign_cast(CType *dt) · 164 unmodified lines
2000}2238}
2001 2239
2002/* store vtop in lvalue pushed on stack */2240/* store vtop in lvalue pushed on stack */
2003void vstore(void)2241ST_FUNC void vstore(void)
2004{2242{
2005 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;2243 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2006 2244
@@ -2161,7 +2399,7 @@ void vstore(void) · 154 unmodified lines
2161}2399}
2162 2400
2163/* post defines POST/PRE add. c is the token ++ or -- */2401/* post defines POST/PRE add. c is the token ++ or -- */
2164void inc(int post, int c)2402ST_FUNC void inc(int post, int c)
2165{2403{
2166 test_lvalue();2404 test_lvalue();
2167 vdup(); /* save lvalue */2405 vdup(); /* save lvalue */
@@ -2879,7 +3117,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) · 711 unmodified lines
2879}3117}
2880 3118
2881/* compute the lvalue VT_LVAL_xxx needed to match type t. */3119/* compute the lvalue VT_LVAL_xxx needed to match type t. */
2882static int lvalue_type(int t)3120ST_FUNC int lvalue_type(int t)
2883{3121{
2884 int bt, r;3122 int bt, r;
2885 r = VT_LVAL;3123 r = VT_LVAL;
@@ -2896,7 +3134,7 @@ static int lvalue_type(int t) · 10 unmodified lines
2896}3134}
2897 3135
2898/* indirection with full error checking and bound check */3136/* indirection with full error checking and bound check */
2899static void indir(void)3137ST_FUNC void indir(void)
2900{3138{
2901 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {3139 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
2902 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)3140 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
@@ -2976,7 +3214,7 @@ static void vpush_tokc(int t) · 73 unmodified lines
2976 vsetc(&type, VT_CONST, &tokc);3214 vsetc(&type, VT_CONST, &tokc);
2977}3215}
2978 3216
2979static void unary(void)3217ST_FUNC void unary(void)
2980{3218{
2981 int n, t, align, size, r;3219 int n, t, align, size, r;
2982 CType type;3220 CType type;
@@ -3444,7 +3682,7 @@ static void uneq(void) · 461 unmodified lines
3444 }3682 }
3445}3683}
3446 3684
3447static void expr_prod(void)3685ST_FUNC void expr_prod(void)
3448{3686{
3449 int t;3687 int t;
3450 3688
@@ -3457,7 +3695,7 @@ static void expr_prod(void) · 6 unmodified lines
3457 }3695 }
3458}3696}
3459 3697
3460static void expr_sum(void)3698ST_FUNC void expr_sum(void)
3461{3699{
3462 int t;3700 int t;
3463 3701
@@ -3745,7 +3983,7 @@ static void expr_eq(void) · 281 unmodified lines
3745 }3983 }
3746}3984}
3747 3985
3748static void gexpr(void)3986ST_FUNC void gexpr(void)
3749{3987{
3750 while (1) {3988 while (1) {
3751 expr_eq();3989 expr_eq();
@@ -3794,7 +4032,7 @@ static void expr_const1(void) · 42 unmodified lines
3794}4032}
3795 4033
3796/* parse an integer constant and return its value. */4034/* parse an integer constant and return its value. */
3797static int expr_const(void)4035ST_FUNC int expr_const(void)
3798{4036{
3799 int c;4037 int c;
3800 expr_const1();4038 expr_const1();
@@ -4848,7 +5086,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 1047 unmodified lines
4848 no_alloc: ;5086 no_alloc: ;
4849}5087}
4850 5088
4851void put_func_debug(Sym *sym)5089static void put_func_debug(Sym *sym)
4852{5090{
4853 char buf[512];5091 char buf[512];
4854 5092
@@ -4951,7 +5189,7 @@ static void gen_function(Sym *sym) · 96 unmodified lines
4951 nocode_wanted = saved_nocode_wanted;5189 nocode_wanted = saved_nocode_wanted;
4952}5190}
4953 5191
4954static void gen_inline_functions(void)5192ST_FUNC void gen_inline_functions(void)
4955{5193{
4956 Sym *sym;5194 Sym *sym;
4957 int *str, inline_generated, i;5195 int *str, inline_generated, i;
@@ -4994,7 +5232,7 @@ static void gen_inline_functions(void) · 36 unmodified lines
4994}5232}
4995 5233
4996/* 'l' is VT_LOCAL or VT_CONST to define default storage type */5234/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4997static void decl(int l)5235ST_FUNC void decl(int l)
4998{5236{
4999 int v, has_init, r;5237 int v, has_init, r;
5000 CType type, btype;5238 CType type, btype;
tccpe.c+62−67
@@ -18,11 +18,7 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#ifdef TCC_TARGET_PE21#include "tcc.h"
22
23#define ST_FN static
24#define ST_DATA static
25#define PUB_FN
26 22
27#ifndef _WIN3223#ifndef _WIN32
28#define stricmp strcasecmp24#define stricmp strcasecmp
@@ -300,7 +296,7 @@ enum { · 271 unmodified lines
300 sec_last296 sec_last
301};297};
302 298
303ST_DATA const DWORD pe_sec_flags[] = {299static const DWORD pe_sec_flags[] = {
304 0x60000020, /* ".text" , */300 0x60000020, /* ".text" , */
305 0xC0000040, /* ".data" , */301 0xC0000040, /* ".data" , */
306 0xC0000080, /* ".bss" , */302 0xC0000080, /* ".bss" , */
@@ -366,7 +362,7 @@ struct pe_info { · 59 unmodified lines
366 362
367/* --------------------------------------------*/363/* --------------------------------------------*/
368 364
369ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)365static const char* get_alt_symbol(char *buffer, const char *symbol)
370{366{
371 const char *p;367 const char *p;
372 p = strrchr(symbol, '@');368 p = strrchr(symbol, '@');
@@ -384,7 +380,7 @@ ST_FN const char* get_alt_symbol(char *buffer, const char *symbol) · 11 unmodified lines
384 return buffer;380 return buffer;
385}381}
386 382
387ST_FN int pe_find_import(TCCState * s1, const char *symbol)383static int pe_find_import(TCCState * s1, const char *symbol)
388{384{
389 char buffer[200];385 char buffer[200];
390 const char *s;386 const char *s;
@@ -399,7 +395,7 @@ ST_FN int pe_find_import(TCCState * s1, const char *symbol) · 8 unmodified lines
399 395
400/*----------------------------------------------------------------------------*/396/*----------------------------------------------------------------------------*/
401 397
402ST_FN int dynarray_assoc(void **pp, int n, int key)398static int dynarray_assoc(void **pp, int n, int key)
403{399{
404 int i;400 int i;
405 for (i = 0; i < n; ++i, ++pp)401 for (i = 0; i < n; ++i, ++pp)
@@ -415,35 +411,35 @@ ST_FN DWORD umin(DWORD a, DWORD b) · 9 unmodified lines
415}411}
416#endif412#endif
417 413
418ST_FN DWORD umax(DWORD a, DWORD b)414static DWORD umax(DWORD a, DWORD b)
419{415{
420 return a < b ? b : a;416 return a < b ? b : a;
421}417}
422 418
423ST_FN DWORD pe_file_align(struct pe_info *pe, DWORD n)419static DWORD pe_file_align(struct pe_info *pe, DWORD n)
424{420{
425 return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);421 return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
426}422}
427 423
428ST_FN DWORD pe_virtual_align(struct pe_info *pe, DWORD n)424static DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
429{425{
430 return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);426 return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
431}427}
432 428
433ST_FN void pe_align_section(Section *s, int a)429static void pe_align_section(Section *s, int a)
434{430{
435 int i = s->data_offset & (a-1);431 int i = s->data_offset & (a-1);
436 if (i)432 if (i)
437 section_ptr_add(s, a - i);433 section_ptr_add(s, a - i);
438}434}
439 435
440ST_FN void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)436static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
441{437{
442 hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;438 hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;
443 hdr->opthdr.DataDirectory[dir].Size = size;439 hdr->opthdr.DataDirectory[dir].Size = size;
444}440}
445 441
446ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)442static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
447{443{
448 if (psum) {444 if (psum) {
449 DWORD sum = *psum;445 DWORD sum = *psum;
@@ -458,7 +454,7 @@ ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum) · 8 unmodified lines
458 return len == fwrite(data, 1, len, fp) ? 0 : -1;454 return len == fwrite(data, 1, len, fp) ? 0 : -1;
459}455}
460 456
461ST_FN void pe_fpad(FILE *fp, DWORD new_pos)457static void pe_fpad(FILE *fp, DWORD new_pos)
462{458{
463 DWORD pos = ftell(fp);459 DWORD pos = ftell(fp);
464 while (++pos <= new_pos)460 while (++pos <= new_pos)
@@ -466,7 +462,7 @@ ST_FN void pe_fpad(FILE *fp, DWORD new_pos) · 1 unmodified line
466}462}
467 463
468/*----------------------------------------------------------------------------*/464/*----------------------------------------------------------------------------*/
469ST_FN int pe_write(struct pe_info *pe)465static int pe_write(struct pe_info *pe)
470{466{
471 static const struct pe_header pe_template = {467 static const struct pe_header pe_template = {
472 {468 {
@@ -745,7 +741,7 @@ ST_FN int pe_write(struct pe_info *pe) · 272 unmodified lines
745#endif741#endif
746/*----------------------------------------------------------------------------*/742/*----------------------------------------------------------------------------*/
747 743
748ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)744static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
749{745{
750 int i;746 int i;
751 int dll_index;747 int dll_index;
@@ -777,7 +773,7 @@ found_dll: · 25 unmodified lines
777}773}
778 774
779/*----------------------------------------------------------------------------*/775/*----------------------------------------------------------------------------*/
780ST_FN void pe_build_imports(struct pe_info *pe)776static void pe_build_imports(struct pe_info *pe)
781{777{
782 int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;778 int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;
783 DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;779 DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;
@@ -860,14 +856,14 @@ struct pe_sort_sym · 76 unmodified lines
860 const char *name;856 const char *name;
861};857};
862 858
863ST_FN int sym_cmp(const void *va, const void *vb)859static int sym_cmp(const void *va, const void *vb)
864{860{
865 const char *ca = (*(struct pe_sort_sym**)va)->name;861 const char *ca = (*(struct pe_sort_sym**)va)->name;
866 const char *cb = (*(struct pe_sort_sym**)vb)->name;862 const char *cb = (*(struct pe_sort_sym**)vb)->name;
867 return strcmp(ca, cb);863 return strcmp(ca, cb);
868}864}
869 865
870ST_FN void pe_build_exports(struct pe_info *pe)866static void pe_build_exports(struct pe_info *pe)
871{867{
872 ElfW(Sym) *sym;868 ElfW(Sym) *sym;
873 int sym_index, sym_end;869 int sym_index, sym_end;
@@ -967,7 +963,7 @@ ST_FN void pe_build_exports(struct pe_info *pe) · 93 unmodified lines
967}963}
968 964
969/* ------------------------------------------------------------- */965/* ------------------------------------------------------------- */
970ST_FN void pe_build_reloc (struct pe_info *pe)966static void pe_build_reloc (struct pe_info *pe)
971{967{
972 DWORD offset, block_ptr, addr;968 DWORD offset, block_ptr, addr;
973 int count, i;969 int count, i;
@@ -1023,7 +1019,7 @@ ST_FN void pe_build_reloc (struct pe_info *pe) · 49 unmodified lines
1023}1019}
1024 1020
1025/* ------------------------------------------------------------- */1021/* ------------------------------------------------------------- */
1026ST_FN int pe_section_class(Section *s)1022static int pe_section_class(Section *s)
1027{1023{
1028 int type, flags;1024 int type, flags;
1029 const char *name;1025 const char *name;
@@ -1055,7 +1051,7 @@ ST_FN int pe_section_class(Section *s) · 25 unmodified lines
1055 return -1;1051 return -1;
1056}1052}
1057 1053
1058ST_FN int pe_assign_addresses (struct pe_info *pe)1054static int pe_assign_addresses (struct pe_info *pe)
1059{1055{
1060 int i, k, o, c;1056 int i, k, o, c;
1061 DWORD addr;1057 DWORD addr;
@@ -1153,7 +1149,7 @@ ST_FN int pe_assign_addresses (struct pe_info *pe) · 91 unmodified lines
1153}1149}
1154 1150
1155/* ------------------------------------------------------------- */1151/* ------------------------------------------------------------- */
1156ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s)1152static void pe_relocate_rva (struct pe_info *pe, Section *s)
1157{1153{
1158 Section *sr = s->reloc;1154 Section *sr = s->reloc;
1159 ElfW_Rel *rel, *rel_end;1155 ElfW_Rel *rel, *rel_end;
@@ -1173,6 +1169,7 @@ ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s) · 13 unmodified lines
1173}1169}
1174 1170
1175/*----------------------------------------------------------------------------*/1171/*----------------------------------------------------------------------------*/
1172
1176static int pe_isafunc(int sym_index)1173static int pe_isafunc(int sym_index)
1177{1174{
1178 Section *sr = text_section->reloc;1175 Section *sr = text_section->reloc;
@@ -1188,7 +1185,7 @@ static int pe_isafunc(int sym_index) · 9 unmodified lines
1188}1185}
1189 1186
1190/*----------------------------------------------------------------------------*/1187/*----------------------------------------------------------------------------*/
1191ST_FN int pe_check_symbols(struct pe_info *pe)1188static int pe_check_symbols(struct pe_info *pe)
1192{1189{
1193 ElfW(Sym) *sym;1190 ElfW(Sym) *sym;
1194 int sym_index, sym_end;1191 int sym_index, sym_end;
@@ -1282,7 +1279,7 @@ ST_FN int pe_check_symbols(struct pe_info *pe) · 87 unmodified lines
1282 1279
1283/*----------------------------------------------------------------------------*/1280/*----------------------------------------------------------------------------*/
1284#ifdef PE_PRINT_SECTIONS1281#ifdef PE_PRINT_SECTIONS
1285ST_FN void pe_print_section(FILE * f, Section * s)1282static void pe_print_section(FILE * f, Section * s)
1286{1283{
1287 /* just if you'r curious */1284 /* just if you'r curious */
1288 BYTE *p, *e, b;1285 BYTE *p, *e, b;
@@ -1404,7 +1401,7 @@ ST_FN void pe_print_section(FILE * f, Section * s) · 115 unmodified lines
1404 fprintf(f, "\n\n");1401 fprintf(f, "\n\n");
1405}1402}
1406 1403
1407ST_FN void pe_print_sections(TCCState *s1, const char *fname)1404static void pe_print_sections(TCCState *s1, const char *fname)
1408{1405{
1409 Section *s;1406 Section *s;
1410 FILE *f;1407 FILE *f;
@@ -1420,34 +1417,8 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname) · 9 unmodified lines
1420#endif1417#endif
1421 1418
1422/* ------------------------------------------------------------- */1419/* ------------------------------------------------------------- */
1423/* helper function for load/store to insert one more indirection */
1424 1420
1425int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))1421static int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
1426{
1427 int t;
1428 if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
1429 return 0;
1430 t = sv->sym->type.t;
1431 if (0 == (t & VT_IMPORT))
1432 return 0;
1433
1434 sv->sym->type.t = t & ~VT_IMPORT;
1435 //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL));
1436
1437 *++vtop = *sv;
1438 vtop->type.t &= ~(VT_ARRAY|VT_IMPORT);
1439 mk_pointer(&vtop->type);
1440 indir();
1441 fn(r, vtop);
1442 --vtop;
1443
1444 sv->sym->type.t = t;
1445 return 1;
1446}
1447
1448/* ------------------------------------------------------------- */
1449
1450ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
1451{1422{
1452 fseek(fp, offset, 0);1423 fseek(fp, offset, 0);
1453 return len == fread(buffer, 1, len, fp);1424 return len == fread(buffer, 1, len, fp);
@@ -1458,7 +1429,7 @@ ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len) · 4 unmodified lines
1458 * as generated by 'windres.exe -O coff ...'.1429 * as generated by 'windres.exe -O coff ...'.
1459 */1430 */
1460 1431
1461ST_FN int pe_load_res(TCCState *s1, FILE *fp)1432static int pe_load_res(TCCState *s1, FILE *fp)
1462{1433{
1463 struct pe_rsrc_header hdr;1434 struct pe_rsrc_header hdr;
1464 Section *rsrc_section;1435 Section *rsrc_section;
@@ -1498,14 +1469,14 @@ quit: · 33 unmodified lines
1498}1469}
1499 1470
1500/* ------------------------------------------------------------- */1471/* ------------------------------------------------------------- */
1501ST_FN char *trimfront(char *p)1472static char *trimfront(char *p)
1502{1473{
1503 while (*p && (unsigned char)*p <= ' ')1474 while (*p && (unsigned char)*p <= ' ')
1504 ++p;1475 ++p;
1505 return p;1476 return p;
1506}1477}
1507 1478
1508ST_FN char *trimback(char *a, char *e)1479static char *trimback(char *a, char *e)
1509{1480{
1510 while (e > a && (unsigned char)e[-1] <= ' ')1481 while (e > a && (unsigned char)e[-1] <= ' ')
1511 --e;1482 --e;
@@ -1513,7 +1484,7 @@ ST_FN char *trimback(char *a, char *e) · 1 unmodified line
1513 return a;1484 return a;
1514}1485}
1515 1486
1516ST_FN char *get_line(char *line, int size, FILE *fp)1487static char *get_line(char *line, int size, FILE *fp)
1517{1488{
1518 if (NULL == fgets(line, size, fp))1489 if (NULL == fgets(line, size, fp))
1519 return NULL;1490 return NULL;
@@ -1522,7 +1493,7 @@ ST_FN char *get_line(char *line, int size, FILE *fp) · 2 unmodified lines
1522}1493}
1523 1494
1524/* ------------------------------------------------------------- */1495/* ------------------------------------------------------------- */
1525ST_FN int pe_load_def(TCCState *s1, FILE *fp)1496static int pe_load_def(TCCState *s1, FILE *fp)
1526{1497{
1527 DLLReference *dllref;1498 DLLReference *dllref;
1528 int state = 0, ret = -1;1499 int state = 0, ret = -1;
@@ -1571,7 +1542,7 @@ quit: · 42 unmodified lines
1571#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY1542#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
1572#include "win32/tools/tiny_impdef.c"1543#include "win32/tools/tiny_impdef.c"
1573 1544
1574ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)1545static int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
1575{1546{
1576 int i = 0;1547 int i = 0;
1577 char *p, *q;1548 char *p, *q;
@@ -1594,7 +1565,7 @@ ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp) · 16 unmodified lines
1594}1565}
1595 1566
1596/* ------------------------------------------------------------- */1567/* ------------------------------------------------------------- */
1597PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd)1568ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
1598{1569{
1599 FILE *fp = fdopen(dup(fd), "rb");1570 FILE *fp = fdopen(dup(fd), "rb");
1600 int ret = -1;1571 int ret = -1;
@@ -1611,7 +1582,7 @@ PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd) · 10 unmodified lines
1611 return ret;1582 return ret;
1612}1583}
1613 1584
1614int pe_add_dll(struct TCCState *s, const char *libname)1585ST_FUNC int pe_add_dll(struct TCCState *s, const char *libname)
1615{1586{
1616 static const char *pat[] = {1587 static const char *pat[] = {
1617 "%s.def", "lib%s.def", "%s.dll", "lib%s.dll", NULL1588 "%s.def", "lib%s.def", "%s.dll", "lib%s.dll", NULL
@@ -1626,6 +1597,32 @@ int pe_add_dll(struct TCCState *s, const char *libname) · 8 unmodified lines
1626 return -1;1597 return -1;
1627}1598}
1628 1599
1600/* ------------------------------------------------------------- */
1601/* helper function for load/store to insert one more indirection */
1602
1603ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))
1604{
1605 int t;
1606 if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
1607 return 0;
1608 t = sv->sym->type.t;
1609 if (0 == (t & VT_IMPORT))
1610 return 0;
1611
1612 sv->sym->type.t = t & ~VT_IMPORT;
1613 //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL));
1614
1615 *++vtop = *sv;
1616 vtop->type.t &= ~(VT_ARRAY|VT_IMPORT);
1617 mk_pointer(&vtop->type);
1618 indir();
1619 fn(r, vtop);
1620 --vtop;
1621
1622 sv->sym->type.t = t;
1623 return 1;
1624}
1625
1629/* ------------------------------------------------------------- */1626/* ------------------------------------------------------------- */
1630#ifdef TCC_TARGET_X86_641627#ifdef TCC_TARGET_X86_64
1631#define PE_STDSYM(n,s) n1628#define PE_STDSYM(n,s) n
@@ -1633,7 +1630,7 @@ int pe_add_dll(struct TCCState *s, const char *libname) · 1 unmodified line
1633#define PE_STDSYM(n,s) "_" n s1630#define PE_STDSYM(n,s) "_" n s
1634#endif1631#endif
1635 1632
1636ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)1633static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
1637{1634{
1638 const char *start_symbol;1635 const char *start_symbol;
1639 unsigned long addr = 0;1636 unsigned long addr = 0;
@@ -1690,7 +1687,7 @@ ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) · 50 unmodified lines
1690 pe->start_addr = addr;1687 pe->start_addr = addr;
1691}1688}
1692 1689
1693PUB_FN int pe_output_file(TCCState * s1, const char *filename)1690ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
1694{1691{
1695 int ret;1692 int ret;
1696 struct pe_info pe;1693 struct pe_info pe;
@@ -1780,5 +1777,3 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename) · 83 unmodified lines
1780}1777}
1781 1778
1782/* ------------------------------------------------------------- */1779/* ------------------------------------------------------------- */
1783#endif /* def TCC_TARGET_PE */
1784/* ------------------------------------------------------------- */
tccpp.c+179−42
@@ -18,6 +18,49 @@ · 17 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21#include "tcc.h"
22
23/********************************************************/
24/* global variables */
25
26ST_DATA int tok_flags;
27/* additional informations about token */
28#define TOK_FLAG_BOL 0x0001 /* beginning of line before */
29#define TOK_FLAG_BOF 0x0002 /* beginning of file before */
30#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
31#define TOK_FLAG_EOF 0x0008 /* end of file */
32
33ST_DATA int parse_flags;
34#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
35#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
36#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
37 token. line feed is also
38 returned at eof */
39#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
40#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
41
42ST_DATA struct BufferedFile *file;
43ST_DATA int ch, tok;
44ST_DATA CValue tokc;
45ST_DATA int *macro_ptr;
46ST_DATA CString tokcstr; /* current parsed string, if any */
47
48/* display benchmark infos */
49ST_DATA int total_lines;
50ST_DATA int total_bytes;
51ST_DATA int tok_ident;
52ST_DATA TokenSym **table_ident;
53
54/* ------------------------------------------------------------------------- */
55
56static int *macro_ptr_allocated;
57static int *unget_saved_macro_ptr;
58static int unget_saved_buffer[TOK_MAX_SIZE + 1];
59static int unget_buffer_enabled;
60static TokenSym *hash_ident[TOK_HASH_SIZE];
61static char token_buf[STRING_MAX_SIZE + 1];
62/* true if isid(c) || isnum(c) */
63static unsigned char isidnum_table[256-CH_EOF];
21 64
22static const char tcc_keywords[] = 65static const char tcc_keywords[] =
23#define DEF(id, str) str "\0"66#define DEF(id, str) str "\0"
@@ -30,21 +73,115 @@ static const unsigned char tok_two_chars[] = · 6 unmodified lines
30 "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"73 "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
31 "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";74 "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
32 75
33/* true if isid(c) || isnum(c) */
34static unsigned char isidnum_table[256-CH_EOF];
35
36
37struct macro_level {76struct macro_level {
38 struct macro_level *prev;77 struct macro_level *prev;
39 int *p;78 int *p;
40};79};
41 80
42static void next_nomacro(void);81ST_FUNC void next_nomacro(void);
43static void next_nomacro_spc(void);82static void next_nomacro_spc(void);
44static void macro_subst(TokenString *tok_str, Sym **nested_list,83static void macro_subst(
45 const int *macro_str, struct macro_level **can_read_stream);84 TokenString *tok_str,
85 Sym **nested_list,
86 const int *macro_str,
87 struct macro_level **can_read_stream
88 );
89
90ST_FUNC void skip(int c)
91{
92 if (tok != c)
93 error("'%c' expected", c);
94 next();
95}
46 96
97/* ------------------------------------------------------------------------- */
98/* CString handling */
99static void cstr_realloc(CString *cstr, int new_size)
100{
101 int size;
102 void *data;
103
104 size = cstr->size_allocated;
105 if (size == 0)
106 size = 8; /* no need to allocate a too small first string */
107 while (size < new_size)
108 size = size * 2;
109 data = tcc_realloc(cstr->data_allocated, size);
110 if (!data)
111 error("memory full");
112 cstr->data_allocated = data;
113 cstr->size_allocated = size;
114 cstr->data = data;
115}
116
117/* add a byte */
118ST_INLN void cstr_ccat(CString *cstr, int ch)
119{
120 int size;
121 size = cstr->size + 1;
122 if (size > cstr->size_allocated)
123 cstr_realloc(cstr, size);
124 ((unsigned char *)cstr->data)[size - 1] = ch;
125 cstr->size = size;
126}
127
128ST_FUNC void cstr_cat(CString *cstr, const char *str)
129{
130 int c;
131 for(;;) {
132 c = *str;
133 if (c == '\0')
134 break;
135 cstr_ccat(cstr, c);
136 str++;
137 }
138}
47 139
140/* add a wide char */
141ST_FUNC void cstr_wccat(CString *cstr, int ch)
142{
143 int size;
144 size = cstr->size + sizeof(nwchar_t);
145 if (size > cstr->size_allocated)
146 cstr_realloc(cstr, size);
147 *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
148 cstr->size = size;
149}
150
151ST_FUNC void cstr_new(CString *cstr)
152{
153 memset(cstr, 0, sizeof(CString));
154}
155
156/* free string and reset it to NULL */
157ST_FUNC void cstr_free(CString *cstr)
158{
159 tcc_free(cstr->data_allocated);
160 cstr_new(cstr);
161}
162
163/* XXX: unicode ? */
164ST_FUNC void add_char(CString *cstr, int c)
165{
166 if (c == '\'' || c == '\"' || c == '\\') {
167 /* XXX: could be more precise if char or string */
168 cstr_ccat(cstr, '\\');
169 }
170 if (c >= 32 && c <= 126) {
171 cstr_ccat(cstr, c);
172 } else {
173 cstr_ccat(cstr, '\\');
174 if (c == '\n') {
175 cstr_ccat(cstr, 'n');
176 } else {
177 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
178 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
179 cstr_ccat(cstr, '0' + (c & 7));
180 }
181 }
182}
183
184/* ------------------------------------------------------------------------- */
48/* allocate a new token */185/* allocate a new token */
49static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)186static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
50{187{
@@ -82,7 +219,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) · 31 unmodified lines
82#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))219#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
83 220
84/* find a token and add it if not found */221/* find a token and add it if not found */
85static TokenSym *tok_alloc(const char *str, int len)222ST_FUNC TokenSym *tok_alloc(const char *str, int len)
86{223{
87 TokenSym *ts, **pts;224 TokenSym *ts, **pts;
88 int i;225 int i;
@@ -107,7 +244,7 @@ static TokenSym *tok_alloc(const char *str, int len) · 18 unmodified lines
107 244
108/* XXX: buffer overflow */245/* XXX: buffer overflow */
109/* XXX: float tokens */246/* XXX: float tokens */
110char *get_tok_str(int v, CValue *cv)247ST_FUNC char *get_tok_str(int v, CValue *cv)
111{248{
112 static char buf[STRING_MAX_SIZE + 1];249 static char buf[STRING_MAX_SIZE + 1];
113 static CString cstr_buf;250 static CString cstr_buf;
@@ -243,13 +380,13 @@ static int tcc_peekc_slow(BufferedFile *bf) · 129 unmodified lines
243 380
244/* return the current character, handling end of block if necessary381/* return the current character, handling end of block if necessary
245 (but not stray) */382 (but not stray) */
246static int handle_eob(void)383ST_FUNC int handle_eob(void)
247{384{
248 return tcc_peekc_slow(file);385 return tcc_peekc_slow(file);
249}386}
250 387
251/* read next char from current input file and handle end of input buffer */388/* read next char from current input file and handle end of input buffer */
252static inline void inp(void)389ST_INLN void inp(void)
253{390{
254 ch = *(++(file->buf_ptr));391 ch = *(++(file->buf_ptr));
255 /* end of buffer/file handling */392 /* end of buffer/file handling */
@@ -334,7 +471,7 @@ static int handle_stray1(uint8_t *p) · 78 unmodified lines
334/* input with '\[\r]\n' handling. Note that this function cannot471/* input with '\[\r]\n' handling. Note that this function cannot
335 handle other characters after '\', so you cannot call it inside472 handle other characters after '\', so you cannot call it inside
336 strings or comments */473 strings or comments */
337static void minp(void)474ST_FUNC void minp(void)
338{475{
339 inp();476 inp();
340 if (ch == '\\') 477 if (ch == '\\')
@@ -380,7 +517,7 @@ static uint8_t *parse_line_comment(uint8_t *p) · 39 unmodified lines
380}517}
381 518
382/* C comments */519/* C comments */
383static uint8_t *parse_comment(uint8_t *p)520ST_FUNC uint8_t *parse_comment(uint8_t *p)
384{521{
385 int c;522 int c;
386 523
@@ -537,7 +674,7 @@ static uint8_t *parse_pp_string(uint8_t *p, · 150 unmodified lines
537 674
538/* skip block of text until #else, #elif or #endif. skip also pairs of675/* skip block of text until #else, #elif or #endif. skip also pairs of
539 #if/#endif */676 #if/#endif */
540void preprocess_skip(void)677static void preprocess_skip(void)
541{678{
542 int a, start_of_line, c, in_warn_or_error;679 int a, start_of_line, c, in_warn_or_error;
543 uint8_t *p;680 uint8_t *p;
@@ -629,7 +766,7 @@ _default: · 85 unmodified lines
629 files */766 files */
630 767
631/* save current parse state in 's' */768/* save current parse state in 's' */
632void save_parse_state(ParseState *s)769ST_FUNC void save_parse_state(ParseState *s)
633{770{
634 s->line_num = file->line_num;771 s->line_num = file->line_num;
635 s->macro_ptr = macro_ptr;772 s->macro_ptr = macro_ptr;
@@ -638,7 +775,7 @@ void save_parse_state(ParseState *s) · 2 unmodified lines
638}775}
639 776
640/* restore parse state from 's' */777/* restore parse state from 's' */
641void restore_parse_state(ParseState *s)778ST_FUNC void restore_parse_state(ParseState *s)
642{779{
643 file->line_num = s->line_num;780 file->line_num = s->line_num;
644 macro_ptr = s->macro_ptr;781 macro_ptr = s->macro_ptr;
@@ -677,7 +814,7 @@ static inline int tok_ext_size(int t) · 32 unmodified lines
677 814
678/* token string handling */815/* token string handling */
679 816
680static inline void tok_str_new(TokenString *s)817ST_INLN void tok_str_new(TokenString *s)
681{818{
682 s->str = NULL;819 s->str = NULL;
683 s->len = 0;820 s->len = 0;
@@ -685,7 +822,7 @@ static inline void tok_str_new(TokenString *s) · 1 unmodified line
685 s->last_line_num = -1;822 s->last_line_num = -1;
686}823}
687 824
688static void tok_str_free(int *str)825ST_FUNC void tok_str_free(int *str)
689{826{
690 tcc_free(str);827 tcc_free(str);
691}828}
@@ -707,7 +844,7 @@ static int *tok_str_realloc(TokenString *s) · 15 unmodified lines
707 return str;844 return str;
708}845}
709 846
710static void tok_str_add(TokenString *s, int t)847ST_FUNC void tok_str_add(TokenString *s, int t)
711{848{
712 int len, *str;849 int len, *str;
713 850
@@ -790,7 +927,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 76 unmodified lines
790}927}
791 928
792/* add the current parse token in token string 's' */929/* add the current parse token in token string 's' */
793static void tok_str_add_tok(TokenString *s)930ST_FUNC void tok_str_add_tok(TokenString *s)
794{931{
795 CValue cval;932 CValue cval;
796 933
@@ -861,7 +998,7 @@ static void tok_str_add_tok(TokenString *s) · 64 unmodified lines
861}998}
862 999
863/* defines handling */1000/* defines handling */
864static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)1001ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
865{1002{
866 Sym *s;1003 Sym *s;
867 1004
@@ -872,7 +1009,7 @@ static inline void define_push(int v, int macro_type, int *str, Sym *first_arg) · 4 unmodified lines
872}1009}
873 1010
874/* undefined a define symbol. Its name is just set to zero */1011/* undefined a define symbol. Its name is just set to zero */
875static void define_undef(Sym *s)1012ST_FUNC void define_undef(Sym *s)
876{1013{
877 int v;1014 int v;
878 v = s->v;1015 v = s->v;
@@ -881,7 +1018,7 @@ static void define_undef(Sym *s) · 2 unmodified lines
881 s->v = 0;1018 s->v = 0;
882}1019}
883 1020
884static inline Sym *define_find(int v)1021ST_INLN Sym *define_find(int v)
885{1022{
886 v -= TOK_IDENT;1023 v -= TOK_IDENT;
887 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))1024 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
@@ -890,7 +1027,7 @@ static inline Sym *define_find(int v) · 2 unmodified lines
890}1027}
891 1028
892/* free define stack until top reaches 'b' */1029/* free define stack until top reaches 'b' */
893static void free_defines(Sym *b)1030ST_FUNC void free_defines(Sym *b)
894{1031{
895 Sym *top, *top1;1032 Sym *top, *top1;
896 int v;1033 int v;
@@ -911,7 +1048,7 @@ static void free_defines(Sym *b) · 14 unmodified lines
911}1048}
912 1049
913/* label lookup */1050/* label lookup */
914static Sym *label_find(int v)1051ST_FUNC Sym *label_find(int v)
915{1052{
916 v -= TOK_IDENT;1053 v -= TOK_IDENT;
917 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))1054 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
@@ -919,7 +1056,7 @@ static Sym *label_find(int v) · 1 unmodified line
919 return table_ident[v]->sym_label;1056 return table_ident[v]->sym_label;
920}1057}
921 1058
922static Sym *label_push(Sym **ptop, int v, int flags)1059ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
923{1060{
924 Sym *s, **ps;1061 Sym *s, **ps;
925 s = sym_push2(ptop, v, 0, 0);1062 s = sym_push2(ptop, v, 0, 0);
@@ -938,7 +1075,7 @@ static Sym *label_push(Sym **ptop, int v, int flags) · 12 unmodified lines
938 1075
939/* pop labels until element last is reached. Look if any labels are1076/* pop labels until element last is reached. Look if any labels are
940 undefined. Define symbols if '&&label' was used. */1077 undefined. Define symbols if '&&label' was used. */
941static void label_pop(Sym **ptop, Sym *slast)1078ST_FUNC void label_pop(Sym **ptop, Sym *slast)
942{1079{
943 Sym *s, *s1;1080 Sym *s, *s1;
944 for(s = *ptop; s != slast; s = s1) {1081 for(s = *ptop; s != slast; s = s1) {
@@ -1017,7 +1154,7 @@ static void tok_print(int *str) · 72 unmodified lines
1017#endif1154#endif
1018 1155
1019/* parse after #define */1156/* parse after #define */
1020static void parse_define(void)1157ST_FUNC void parse_define(void)
1021{1158{
1022 Sym *s, *first, **ps;1159 Sym *s, *first, **ps;
1023 int v, t, varg, is_vaargs, spc;1160 int v, t, varg, is_vaargs, spc;
@@ -1193,7 +1330,7 @@ static void pragma_parse(TCCState *s1) · 169 unmodified lines
1193}1330}
1194 1331
1195/* is_bof is true if first non space token at beginning of file */1332/* is_bof is true if first non space token at beginning of file */
1196static void preprocess(int is_bof)1333ST_FUNC void preprocess(int is_bof)
1197{1334{
1198 TCCState *s1 = tcc_state;1335 TCCState *s1 = tcc_state;
1199 int i, c, n, saved_parse_flags;1336 int i, c, n, saved_parse_flags;
@@ -1350,7 +1487,7 @@ static void preprocess(int is_bof) · 150 unmodified lines
1350 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1);1487 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1);
1351 file = f;1488 file = f;
1352 /* add include file debug info */1489 /* add include file debug info */
1353 if (tcc_state->do_debug) {1490 if (s1->do_debug) {
1354 put_stabs(file->filename, N_BINCL, 0, 0, 0);1491 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1355 }1492 }
1356 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;1493 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 · 241 unmodified lines
1598#define BN_SIZE 21735#define BN_SIZE 2
1599 1736
1600/* bn = (bn << shift) | or_val */1737/* bn = (bn << shift) | or_val */
1601void bn_lshift(unsigned int *bn, int shift, int or_val)1738static void bn_lshift(unsigned int *bn, int shift, int or_val)
1602{1739{
1603 int i;1740 int i;
1604 unsigned int v;1741 unsigned int v;
@@ -1609,7 +1746,7 @@ void bn_lshift(unsigned int *bn, int shift, int or_val) · 4 unmodified lines
1609 }1746 }
1610}1747}
1611 1748
1612void bn_zero(unsigned int *bn)1749static void bn_zero(unsigned int *bn)
1613{1750{
1614 int i;1751 int i;
1615 for(i=0;i<BN_SIZE;i++) {1752 for(i=0;i<BN_SIZE;i++) {
@@ -1619,7 +1756,7 @@ void bn_zero(unsigned int *bn) · 3 unmodified lines
1619 1756
1620/* parse number in null terminated string 'p' and return it in the1757/* parse number in null terminated string 'p' and return it in the
1621 current token */1758 current token */
1622void parse_number(const char *p)1759static void parse_number(const char *p)
1623{1760{
1624 int b, t, shift, frac_bits, s, exp_val, ch;1761 int b, t, shift, frac_bits, s, exp_val, ch;
1625 char *q;1762 char *q;
@@ -2353,7 +2490,7 @@ static void next_nomacro_spc(void) · 727 unmodified lines
2353 }2490 }
2354}2491}
2355 2492
2356static void next_nomacro(void)2493ST_FUNC void next_nomacro(void)
2357{2494{
2358 do {2495 do {
2359 next_nomacro_spc();2496 next_nomacro_spc();
@@ -2734,7 +2871,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 374 unmodified lines
2734}2871}
2735 2872
2736/* return next token with macro substitution */2873/* return next token with macro substitution */
2737static void next(void)2874ST_FUNC void next(void)
2738{2875{
2739 Sym *nested_list, *s;2876 Sym *nested_list, *s;
2740 TokenString str;2877 TokenString str;
@@ -2790,7 +2927,7 @@ static void next(void) · 49 unmodified lines
2790 2927
2791/* push back current token and set current token to 'last_tok'. Only2928/* push back current token and set current token to 'last_tok'. Only
2792 identifier case handled for labels. */2929 identifier case handled for labels. */
2793static inline void unget_tok(int last_tok)2930ST_INLN void unget_tok(int last_tok)
2794{2931{
2795 int i, n;2932 int i, n;
2796 int *q;2933 int *q;
@@ -2809,7 +2946,7 @@ static inline void unget_tok(int last_tok) · 12 unmodified lines
2809 2946
2810/* better than nothing, but needs extension to handle '-E' option2947/* better than nothing, but needs extension to handle '-E' option
2811 correctly too */2948 correctly too */
2812static void preprocess_init(TCCState *s1)2949ST_FUNC void preprocess_init(TCCState *s1)
2813{2950{
2814 s1->include_stack_ptr = s1->include_stack;2951 s1->include_stack_ptr = s1->include_stack;
2815 /* XXX: move that before to avoid having to initialize2952 /* XXX: move that before to avoid having to initialize
@@ -2823,7 +2960,7 @@ static void preprocess_init(TCCState *s1) · 7 unmodified lines
2823 s1->pack_stack_ptr = s1->pack_stack;2960 s1->pack_stack_ptr = s1->pack_stack;
2824}2961}
2825 2962
2826void preprocess_new()2963ST_FUNC void preprocess_new()
2827{2964{
2828 int i, c;2965 int i, c;
2829 const char *p, *r;2966 const char *p, *r;
@@ -2852,9 +2989,10 @@ void preprocess_new() · 22 unmodified lines
2852}2989}
2853 2990
2854/* Preprocess the current file */2991/* Preprocess the current file */
2855static int tcc_preprocess(TCCState *s1)2992ST_FUNC int tcc_preprocess(TCCState *s1)
2856{2993{
2857 Sym *define_start;2994 Sym *define_start;
2995
2858 BufferedFile *file_ref, **iptr, **iptr_new;2996 BufferedFile *file_ref, **iptr, **iptr_new;
2859 int token_seen, line_ref, d;2997 int token_seen, line_ref, d;
2860 const char *s;2998 const char *s;
@@ -2868,8 +3006,8 @@ static int tcc_preprocess(TCCState *s1) · 7 unmodified lines
2868 token_seen = 0;3006 token_seen = 0;
2869 line_ref = 0;3007 line_ref = 0;
2870 file_ref = NULL;3008 file_ref = NULL;
2871
2872 iptr = s1->include_stack_ptr;3009 iptr = s1->include_stack_ptr;
3010
2873 for (;;) {3011 for (;;) {
2874 next();3012 next();
2875 if (tok == TOK_EOF) {3013 if (tok == TOK_EOF) {
@@ -2904,7 +3042,6 @@ print_line: · 28 unmodified lines
2904 }3042 }
2905 fputs(get_tok_str(tok, &tokc), s1->outfile);3043 fputs(get_tok_str(tok, &tokc), s1->outfile);
2906 }3044 }
2907 free_defines(define_start); 3045 free_defines(define_start);
2908 return 0;3046 return 0;
2909}3047}
2910
tccrun.c+22−21
@@ -1,5 +1,5 @@
1/*1/*
2 * TCC - Tiny C Compiler2 * TCC - Tiny C Compiler - Support for -run switch
3 *3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard4 * Copyright (c) 2001-2004 Fabrice Bellard
5 *5 *
@@ -18,7 +18,7 @@ · 12 unmodified lines
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */19 */
20 20
21/* tccrun.c - support for tcc -run */21#include "tcc.h"
22 22
23#ifdef _WIN3223#ifdef _WIN32
24#define ucontext_t CONTEXT24#define ucontext_t CONTEXT
@@ -26,7 +26,7 @@ · 1 unmodified line
26 26
27static void set_pages_executable(void *ptr, unsigned long length);27static void set_pages_executable(void *ptr, unsigned long length);
28static void set_exception_handler(void);28static void set_exception_handler(void);
29static int rt_get_caller_pc(unsigned long *paddr, ucontext_t *uc, int level);29static int rt_get_caller_pc(uplong *paddr, ucontext_t *uc, int level);
30static void rt_error(ucontext_t *uc, const char *fmt, ...);30static void rt_error(ucontext_t *uc, const char *fmt, ...);
31static int tcc_relocate_ex(TCCState *s1, void *ptr);31static int tcc_relocate_ex(TCCState *s1, void *ptr);
32 32
@@ -173,8 +173,8 @@ static void set_pages_executable(void *ptr, unsigned long length) · 140 unmodified lines
173 VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);173 VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
174#else174#else
175 unsigned long start, end;175 unsigned long start, end;
176 start = (unsigned long)ptr & ~(PAGESIZE - 1);176 start = (uplong)ptr & ~(PAGESIZE - 1);
177 end = (unsigned long)ptr + length;177 end = (uplong)ptr + length;
178 end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);178 end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
179 mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);179 mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
180#endif180#endif
@@ -185,7 +185,7 @@ static void set_pages_executable(void *ptr, unsigned long length) · 4 unmodified lines
185 185
186/* print the position in the source file of PC value 'pc' by reading186/* print the position in the source file of PC value 'pc' by reading
187 the stabs debug information */187 the stabs debug information */
188static unsigned long rt_printline(unsigned long wanted_pc)188static uplong rt_printline(uplong wanted_pc)
189{189{
190 Stab_Sym *sym, *sym_end;190 Stab_Sym *sym, *sym_end;
191 char func_name[128], last_func_name[128];191 char func_name[128], last_func_name[128];
@@ -194,7 +194,7 @@ static unsigned long rt_printline(unsigned long wanted_pc) · 2 unmodified lines
194 int incl_index, len, last_line_num, i;194 int incl_index, len, last_line_num, i;
195 const char *str, *p;195 const char *str, *p;
196 196
197 fprintf(stderr, "0x%08lx:", wanted_pc);197 fprintf(stderr, "0x%08lx:", (unsigned long)wanted_pc);
198 198
199 func_name[0] = '\0';199 func_name[0] = '\0';
200 func_addr = 0;200 func_addr = 0;
@@ -311,7 +311,7 @@ static unsigned long rt_printline(unsigned long wanted_pc) · 110 unmodified lines
311static void rt_error(ucontext_t *uc, const char *fmt, ...)311static void rt_error(ucontext_t *uc, const char *fmt, ...)
312{312{
313 va_list ap;313 va_list ap;
314 unsigned long pc;314 uplong pc;
315 int i;315 int i;
316 316
317 va_start(ap, fmt);317 va_start(ap, fmt);
@@ -327,7 +327,7 @@ static void rt_error(ucontext_t *uc, const char *fmt, ...) · 9 unmodified lines
327 else327 else
328 fprintf(stderr, "by ");328 fprintf(stderr, "by ");
329 pc = rt_printline(pc);329 pc = rt_printline(pc);
330 if (pc == (unsigned long)rt_prog_main && pc)330 if (pc == (uplong)rt_prog_main && pc)
331 break;331 break;
332 }332 }
333 exit(255);333 exit(255);
@@ -505,11 +505,15 @@ static void set_exception_handler(void) · 171 unmodified lines
505 SetUnhandledExceptionFilter(cpu_exception_handler);505 SetUnhandledExceptionFilter(cpu_exception_handler);
506}506}
507 507
508#ifdef _WIN64
509#define Eip Rip
510#define Ebp Rbp
511#endif
512
508/* return the PC at frame level 'level'. Return non zero if not found */513/* return the PC at frame level 'level'. Return non zero if not found */
509static int rt_get_caller_pc(unsigned long *paddr,514static int rt_get_caller_pc(uplong *paddr, CONTEXT *uc, int level)
510 CONTEXT *uc, int level)
511{515{
512 unsigned long fp;516 uplong fp;
513 int i;517 int i;
514 518
515 if (level == 0) {519 if (level == 0) {
@@ -521,13 +525,16 @@ static int rt_get_caller_pc(unsigned long *paddr, · 5 unmodified lines
521 /* XXX: check address validity with program info */525 /* XXX: check address validity with program info */
522 if (fp <= 0x1000 || fp >= 0xc0000000)526 if (fp <= 0x1000 || fp >= 0xc0000000)
523 return -1;527 return -1;
524 fp = ((unsigned long *)fp)[0];528 fp = ((uplong*)fp)[0];
525 }529 }
526 *paddr = ((unsigned long *)fp)[1];530 *paddr = ((uplong*)fp)[1];
527 return 0;531 return 0;
528 }532 }
529}533}
530 534
535#undef Eip
536#undef Ebp
537
531#endif /* _WIN32 */538#endif /* _WIN32 */
532#endif /* CONFIG_TCC_BACKTRACE */539#endif /* CONFIG_TCC_BACKTRACE */
533/* ------------------------------------------------------------- */540/* ------------------------------------------------------------- */
@@ -584,13 +591,7 @@ void *resolve_sym(TCCState *s1, const char *symbol) · 50 unmodified lines
584 return NULL;591 return NULL;
585}592}
586 593
587#elif defined(_WIN32)594#elif !defined(_WIN32)
588
589#define dlclose FreeLibrary
590
591#else
592
593#include <dlfcn.h>
594 595
595void *resolve_sym(TCCState *s1, const char *sym)596void *resolve_sym(TCCState *s1, const char *sym)
596{597{
x86_64-gen.c+24−14
@@ -20,10 +20,11 @@ · 19 unmodified lines
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */21 */
22 22
23#include <assert.h>23#ifdef TARGET_DEFS_ONLY
24 24
25/* number of available registers */25/* number of available registers */
26#define NB_REGS 526#define NB_REGS 5
27#define NB_ASM_REGS 8
27 28
28/* a register can belong to several classes. The classes must be29/* a register can belong to several classes. The classes must be
29 sorted from more general to more precise (see gv2() code which does30 sorted from more general to more precise (see gv2() code which does
@@ -60,14 +61,6 @@ enum { · 30 unmodified lines
60#define REX_BASE(reg) (((reg) >> 3) & 1)61#define REX_BASE(reg) (((reg) >> 3) & 1)
61#define REG_VALUE(reg) ((reg) & 7)62#define REG_VALUE(reg) ((reg) & 7)
62 63
63const int reg_classes[NB_REGS] = {
64 /* eax */ RC_INT | RC_RAX,
65 /* ecx */ RC_INT | RC_RCX,
66 /* edx */ RC_INT | RC_RDX,
67 /* xmm0 */ RC_FLOAT | RC_XMM0,
68 /* st0 */ RC_ST0,
69};
70
71/* return registers for function */64/* return registers for function */
72#define REG_IRET TREG_RAX /* single word int return register */65#define REG_IRET TREG_RAX /* single word int return register */
73#define REG_LRET TREG_RDX /* second word return register (for long long) */66#define REG_LRET TREG_RDX /* second word return register (for long long) */
@@ -85,6 +78,9 @@ const int reg_classes[NB_REGS] = { · 11 unmodified lines
85/* maximum alignment (for aligned attribute support) */78/* maximum alignment (for aligned attribute support) */
86#define MAX_ALIGN 879#define MAX_ALIGN 8
87 80
81ST_FUNC void gen_opl(int op);
82ST_FUNC void gen_le64(int64_t c);
83
88/******************************************************/84/******************************************************/
89/* ELF defines */85/* ELF defines */
90 86
@@ -100,6 +96,18 @@ const int reg_classes[NB_REGS] = { · 9 unmodified lines
100#define ELF_PAGE_SIZE 0x100096#define ELF_PAGE_SIZE 0x1000
101 97
102/******************************************************/98/******************************************************/
99#else /* ! TARGET_DEFS_ONLY */
100/******************************************************/
101#include "tcc.h"
102#include <assert.h>
103
104ST_DATA const int reg_classes[NB_REGS] = {
105 /* eax */ RC_INT | RC_RAX,
106 /* ecx */ RC_INT | RC_RCX,
107 /* edx */ RC_INT | RC_RDX,
108 /* xmm0 */ RC_FLOAT | RC_XMM0,
109 /* st0 */ RC_ST0,
110};
103 111
104static unsigned long func_sub_sp_offset;112static unsigned long func_sub_sp_offset;
105static int func_ret_sub;113static int func_ret_sub;
@@ -184,7 +192,7 @@ static int is_sse_float(int t) { · 78 unmodified lines
184}192}
185 193
186/* instruction + 4 bytes data. Return the address of the data */194/* instruction + 4 bytes data. Return the address of the data */
187static int oad(int c, int s)195ST_FUNC int oad(int c, int s)
188{196{
189 int ind1;197 int ind1;
190 198
@@ -198,7 +206,7 @@ static int oad(int c, int s) · 7 unmodified lines
198 return s;206 return s;
199}207}
200 208
201static void gen_addr32(int r, Sym *sym, int c)209ST_FUNC void gen_addr32(int r, Sym *sym, int c)
202{210{
203 if (r & VT_SYM)211 if (r & VT_SYM)
204 greloc(cur_text_section, sym, ind, R_X86_64_32);212 greloc(cur_text_section, sym, ind, R_X86_64_32);
@@ -206,7 +214,7 @@ static void gen_addr32(int r, Sym *sym, int c) · 1 unmodified line
206}214}
207 215
208/* output constant with relocation if 'r & VT_SYM' is true */216/* output constant with relocation if 'r & VT_SYM' is true */
209static void gen_addr64(int r, Sym *sym, int64_t c)217ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
210{218{
211 if (r & VT_SYM)219 if (r & VT_SYM)
212 greloc(cur_text_section, sym, ind, R_X86_64_64);220 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) · 1 unmodified line
214}222}
215 223
216/* output constant with relocation if 'r & VT_SYM' is true */224/* output constant with relocation if 'r & VT_SYM' is true */
217static void gen_addrpc32(int r, Sym *sym, int c)225ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
218{226{
219 if (r & VT_SYM)227 if (r & VT_SYM)
220 greloc(cur_text_section, sym, ind, R_X86_64_PC32);228 greloc(cur_text_section, sym, ind, R_X86_64_PC32);
@@ -1537,3 +1545,5 @@ void ggoto(void) · 1316 unmodified lines
1537 1545
1538/* end of x86-64 code generator */1546/* end of x86-64 code generator */
1539/*************************************************************/1547/*************************************************************/
1548#endif /* ! TARGET_DEFS_ONLY */
1549/******************************************************/

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t