If you want that, run: make NOTALLINONE=1
Unified · Split
| @@ -113,11 +113,13 @@ ifdef CONFIG_CROSS · 112 unmodified lines | |||
| 113 | PROGS+=$(PROGS_CROSS) | 113 | PROGS+=$(PROGS_CROSS) |
| 114 | endif | 114 | endif |
| 115 | 115 | ||
| 116 | # NOTALLINONE = 1 | ||
| 117 | |||
| 116 | all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF) | 118 | all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF) |
| 117 | 119 | ||
| 118 | # Host Tiny C Compiler | 120 | # Host Tiny C Compiler |
| 119 | tcc$(EXESUF): $(NATIVE_FILES) | 121 | tcc$(EXESUF): tcc.o libtcc.a |
| 120 | $(CC) -o $@ $< $(NATIVE_TARGET) $(CFLAGS) $(LIBS) | 122 | $(CC) -o $@ $^ $(LIBS) |
| 121 | 123 | ||
| 122 | # Cross Tiny C Compilers | 124 | # Cross Tiny C Compilers |
| 123 | i386-tcc$(EXESUF): $(I386_FILES) | 125 | i386-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 test | 155 | # libtcc generation and test |
| 154 | libtcc.o: $(NATIVE_FILES) | ||
| 155 | $(CC) -o $@ -c libtcc.c $(NATIVE_TARGET) $(CFLAGS) | ||
| 156 | 156 | ||
| 157 | libtcc.a: libtcc.o | 157 | ifdef NOTALLINONE |
| 158 | LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES)))) | ||
| 159 | LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES)) | ||
| 160 | $(LIBTCC_OBJ) : DEFINES += -DNOTALLINONE | ||
| 161 | else | ||
| 162 | LIBTCC_OBJ = libtcc.o | ||
| 163 | LIBTCC_INC = $(NATIVE_FILES) | ||
| 164 | endif | ||
| 165 | |||
| 166 | tcc.o : DEFINES += -DNOTALLINONE | ||
| 167 | |||
| 168 | $(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC) | ||
| 169 | $(CC) -o $@ -c $< $(NATIVE_TARGET) $(CFLAGS) $(DEFINES) | ||
| 170 | |||
| 171 | libtcc.a: $(LIBTCC_OBJ) | ||
| 158 | $(AR) rcs $@ $^ | 172 | $(AR) rcs $@ $^ |
| 159 | 173 | ||
| 160 | libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a | 174 | libtcc_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 subdir | 276 | # in tests subdir |
| 263 | test clean: | 277 | %est: |
| 264 | $(MAKE) -C tests $@ | 278 | $(MAKE) -C tests $@ |
| 265 | 279 | ||
| 266 | config.mak: | 280 | clean: |
| 267 | @echo Running configure ... | ||
| 268 | @./configure | ||
| 269 | |||
| 270 | # clean | ||
| 271 | clean: local_clean | ||
| 272 | local_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 | ||
| 275 | distclean: clean | 284 | distclean: clean |
| 276 | rm -vf config.h config.mak config.texi tcc.1 | 285 | rm -vf config.h config.mak config.texi tcc.1 |
| 277 | 286 | ||
| 287 | config.mak: | ||
| 288 | @echo Running configure ... | ||
| 289 | @./configure | ||
| 290 | |||
| 278 | endif # ifeq ($(TOP),.) | 291 | endif # ifeq ($(TOP),.) |
| @@ -20,11 +20,12 @@ · 19 unmodified lines | |||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * 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_EABI | 25 | #ifdef TCC_ARM_EABI |
| 24 | #define TCC_ARM_VFP | 26 | #define TCC_ARM_VFP |
| 25 | #endif | 27 | #endif |
| 26 | 28 | ||
| 27 | |||
| 28 | /* number of available registers */ | 29 | /* number of available registers */ |
| 29 | #ifdef TCC_ARM_VFP | 30 | #ifdef TCC_ARM_VFP |
| 30 | #define NB_REGS 13 | 31 | #define NB_REGS 13 |
| @@ -75,32 +76,6 @@ enum { · 44 unmodified lines | |||
| 75 | #endif | 76 | #endif |
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | const 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 | |||
| 96 | static int two2mask(int a,int b) { | ||
| 97 | return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int regmask(int r) { | ||
| 101 | return reg_classes[r]&~(RC_INT|RC_FLOAT); | ||
| 102 | } | ||
| 103 | |||
| 104 | #ifdef TCC_ARM_VFP | 79 | #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 | #endif | 81 | #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 0x1000 | 146 | #define ELF_PAGE_SIZE 0x1000 |
| 172 | 147 | ||
| 173 | /******************************************************/ | 148 | /******************************************************/ |
| 149 | #else /* ! TARGET_DEFS_ONLY */ | ||
| 150 | /******************************************************/ | ||
| 151 | #include "tcc.h" | ||
| 152 | |||
| 153 | ST_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 | |||
| 174 | static unsigned long func_sub_sp_offset,last_itod_magic; | 171 | static unsigned long func_sub_sp_offset,last_itod_magic; |
| 175 | static int leaffunc; | 172 | static int leaffunc; |
| 176 | 173 | ||
| 177 | void o(unsigned long i) | 174 | static int two2mask(int a,int b) { |
| 175 | return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT); | ||
| 176 | } | ||
| 177 | |||
| 178 | static int regmask(int r) { | ||
| 179 | return reg_classes[r]&~(RC_INT|RC_FLOAT); | ||
| 180 | } | ||
| 181 | |||
| 182 | /******************************************************/ | ||
| 183 | |||
| 184 | void 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 | ||
| 307 | unsigned long encbranch(int pos,int addr,int fail) | 314 | ST_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. */ |
| 1574 | void gen_cvt_itof1(int t) | 1581 | ST_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 | /*************************************************************/ | ||
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * 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_C67 | 23 | //#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 | ||
| 88 | const 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) \ |
| 124 | do {\ | 96 | do {\ |
| 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 | ||
| 137 | int NoOfCurFuncArgs; | ||
| 138 | int TranslateStackToReg[NoCallArgsPassedOnStack]; | ||
| 139 | int ParamLocOnStack[NoCallArgsPassedOnStack]; | ||
| 140 | int 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_PARAMS | 102 | //#define INVERT_FUNC_PARAMS |
| 145 | 103 | ||
| 146 | /* defined if structures are passed as pointers. Otherwise structures | 104 | /* defined if structures are passed as pointers. Otherwise structures |
| @@ -171,7 +129,52 @@ int TotalBytesPushedOnStack; · 24 unmodified lines | |||
| 171 | #define ELF_PAGE_SIZE 0x1000 | 129 | #define ELF_PAGE_SIZE 0x1000 |
| 172 | 130 | ||
| 173 | /******************************************************/ | 131 | /******************************************************/ |
| 132 | #else /* ! TARGET_DEFS_ONLY */ | ||
| 133 | /******************************************************/ | ||
| 134 | #include "tcc.h" | ||
| 135 | |||
| 136 | ST_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 | ||
| 172 | int NoOfCurFuncArgs; | ||
| 173 | int TranslateStackToReg[NoCallArgsPassedOnStack]; | ||
| 174 | int ParamLocOnStack[NoCallArgsPassedOnStack]; | ||
| 175 | int TotalBytesPushedOnStack; | ||
| 174 | 176 | ||
| 177 | /******************************************************/ | ||
| 175 | static unsigned long func_sub_sp_offset; | 178 | static unsigned long func_sub_sp_offset; |
| 176 | static int func_ret_sub; | 179 | static 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 | /*************************************************************/ |
| @@ -19,7 +19,11 @@ · 18 unmodified lines | |||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * 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 3 | 25 | #define MAX_OPERANDS 3 |
| 26 | #define NB_SAVED_REGS 3 | ||
| 23 | 27 | ||
| 24 | #define TOK_ASM_first TOK_ASM_clc | 28 | #define TOK_ASM_first TOK_ASM_clc |
| 25 | #define TOK_ASM_last TOK_ASM_emms | 29 | #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 | ||
| 401 | static void gen_expr32(ExprValue *pe) | 405 | /* XXX: unify with C code output ? */ |
| 406 | ST_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 | ||
| 557 | static void asm_opcode(TCCState *s1, int opcode) | 562 | ST_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 | #endif | 971 | #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 lowest | 974 | /* return the constraint priority (we allocate first the lowest |
| 973 | numbered constraints) */ | 975 | numbered constraints) */ |
| 974 | static inline int constraint_priority(const char *str) | 976 | static 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 | ||
| 1033 | static void asm_compute_constraints(ASMOperand *operands, | 1035 | ST_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 | #endif | 1264 | #endif |
| 1263 | } | 1265 | } |
| 1264 | 1266 | ||
| 1265 | static void subst_asm_operand(CString *add_str, | 1267 | ST_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 */ |
| 1359 | static void asm_gen_code(ASMOperand *operands, int nb_operands, | 1361 | ST_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 | ||
| 1453 | static void asm_clobber(uint8_t *clobber_regs, const char *str) | 1455 | ST_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; |
| @@ -18,8 +18,11 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * 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 4 | 24 | #define NB_REGS 4 |
| 25 | #define NB_ASM_REGS 8 | ||
| 23 | 26 | ||
| 24 | /* a register can belong to several classes. The classes must be | 27 | /* a register can belong to several classes. The classes must be |
| 25 | sorted from more general to more precise (see gv2() code which does | 28 | 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 | ||
| 45 | const 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 8 | 67 | #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 0x1000 | 84 | #define ELF_PAGE_SIZE 0x1000 |
| 86 | 85 | ||
| 87 | /******************************************************/ | 86 | /******************************************************/ |
| 87 | #else /* ! TARGET_DEFS_ONLY */ | ||
| 88 | /******************************************************/ | ||
| 89 | #include "tcc.h" | ||
| 90 | |||
| 91 | ST_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 | ||
| 89 | static unsigned long func_sub_sp_offset; | 98 | static unsigned long func_sub_sp_offset; |
| 90 | static int func_ret_sub; | 99 | static int func_ret_sub; |
| @@ -93,7 +102,7 @@ static unsigned long func_bound_offset; · 2 unmodified lines | |||
| 93 | #endif | 102 | #endif |
| 94 | 103 | ||
| 95 | /* XXX: make it faster ? */ | 104 | /* XXX: make it faster ? */ |
| 96 | void g(int c) | 105 | ST_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 | ||
| 106 | void o(unsigned int c) | 115 | ST_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 | ||
| 114 | void gen_le16(int v) | 123 | ST_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 | ||
| 120 | void gen_le32(int c) | 129 | ST_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 */ |
| 129 | void gsym_addr(int t, int a) | 138 | ST_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 | ||
| 140 | void gsym(int t) | 149 | ST_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 oad | 156 | #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 */ |
| 150 | static int oad(int c, int s) | 159 | ST_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 */ |
| 165 | static void gen_addr32(int r, Sym *sym, int c) | 174 | ST_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 | ||
| 172 | static void gen_addrpc32(int r, Sym *sym, int c) | 181 | ST_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' */ |
| 203 | void load(int r, SValue *sv) | 212 | ST_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' */ |
| 272 | void store(int r, SValue *v) | 281 | ST_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, then | 358 | /* Generate function call. The function address is pushed first, then |
| 350 | all the parameters in call order. This functions pops all the | 359 | all the parameters in call order. This functions pops all the |
| 351 | parameters and the function address. */ | 360 | parameters and the function address. */ |
| 352 | void gfunc_call(int nb_args) | 361 | ST_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 | #endif | 451 | #endif |
| 443 | 452 | ||
| 444 | /* generate function prolog of type 't' */ | 453 | /* generate function prolog of type 't' */ |
| 445 | void gfunc_prolog(CType *func_type) | 454 | ST_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 */ |
| 527 | void gfunc_epilog(void) | 536 | ST_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 */ |
| 598 | int gjmp(int t) | 607 | ST_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 */ |
| 604 | void gjmp_addr(int a) | 613 | ST_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 */ |
| 617 | int gtst(int inv, int t) | 626 | ST_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 */ |
| 662 | void gen_opi(int op) | 671 | ST_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. The | 802 | /* 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 */ |
| 796 | void gen_opf(int op) | 805 | ST_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. */ |
| 908 | void gen_cvt_itof(int t) | 917 | ST_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 */ |
| 938 | void gen_cvt_ftoi(int t) | 947 | ST_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 */ |
| 989 | void gen_cvt_ftof(int t) | 998 | ST_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 */ |
| 996 | void ggoto(void) | 1005 | ST_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_BCHECK | 1012 | #ifdef CONFIG_TCC_BCHECK |
| 1004 | 1013 | ||
| 1005 | /* generate a bounded pointer addition */ | 1014 | /* generate a bounded pointer addition */ |
| 1006 | void gen_bounded_ptr_add(void) | 1015 | ST_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 is | 1036 | /* patch pointer addition in vtop so that pointer dereferencing is |
| 1028 | also tested */ | 1037 | also tested */ |
| 1029 | void gen_bounded_ptr_deref(void) | 1038 | ST_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 | /*************************************************************/ | ||
| @@ -23,344 +23,70 @@ · 22 unmodified lines | |||
| 23 | /********************************************************/ | 23 | /********************************************************/ |
| 24 | /* global variables */ | 24 | /* global variables */ |
| 25 | 25 | ||
| 26 | /* display benchmark infos */ | ||
| 27 | int total_lines; | ||
| 28 | int total_bytes; | ||
| 29 | |||
| 30 | /* parser */ | ||
| 31 | static struct BufferedFile *file; | ||
| 32 | static int ch, tok; | ||
| 33 | static CValue tokc; | ||
| 34 | static CString tokcstr; /* current parsed string, if any */ | ||
| 35 | /* additional informations about token */ | ||
| 36 | static 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 | |||
| 42 | static int *macro_ptr, *macro_ptr_allocated; | ||
| 43 | static int *unget_saved_macro_ptr; | ||
| 44 | static int unget_saved_buffer[TOK_MAX_SIZE + 1]; | ||
| 45 | static int unget_buffer_enabled; | ||
| 46 | static 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 | |||
| 55 | static Section *text_section, *data_section, *bss_section; /* predefined sections */ | ||
| 56 | static Section *cur_text_section; /* current section where function code is | ||
| 57 | generated */ | ||
| 58 | #ifdef CONFIG_TCC_ASM | ||
| 59 | static Section *last_text_section; /* to handle .previous asm directive */ | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #ifdef CONFIG_TCC_BCHECK | ||
| 63 | /* bound check related sections */ | ||
| 64 | static Section *bounds_section; /* contains global data bound description */ | ||
| 65 | static Section *lbounds_section; /* contains local data bound description */ | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* symbol sections */ | ||
| 69 | static Section *symtab_section, *strtab_section; | ||
| 70 | |||
| 71 | /* debug sections */ | ||
| 72 | static 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 | */ | ||
| 79 | static int rsym, anon_sym, ind, loc; | ||
| 80 | /* expression generation modifiers */ | ||
| 81 | static int const_wanted; /* true if constant wanted */ | ||
| 82 | static int nocode_wanted; /* true if no code generation wanted for an expression */ | ||
| 83 | static int global_expr; /* true if compound literals must be allocated | ||
| 84 | globally (used during initializers parsing */ | ||
| 85 | static CType func_vt; /* current function return type (used by return | ||
| 86 | instruction) */ | ||
| 87 | static int func_vc; | ||
| 88 | static int last_line_num, last_ind, func_ind; /* debug last line number and pc */ | ||
| 89 | static int tok_ident; | ||
| 90 | static TokenSym **table_ident; | ||
| 91 | static TokenSym *hash_ident[TOK_HASH_SIZE]; | ||
| 92 | static char token_buf[STRING_MAX_SIZE + 1]; | ||
| 93 | static char *funcname; | ||
| 94 | static Sym *global_stack, *local_stack; | ||
| 95 | static Sym *define_stack; | ||
| 96 | static Sym *global_label_stack, *local_label_stack; | ||
| 97 | /* symbol allocator */ | ||
| 98 | #define SYM_POOL_NB (8192 / sizeof(Sym)) | ||
| 99 | static Sym *sym_free_first; | ||
| 100 | static void **sym_pools; | ||
| 101 | static int nb_sym_pools; | ||
| 102 | |||
| 103 | static SValue vstack[VSTACK_SIZE], *vtop; | ||
| 104 | /* some predefined types */ | ||
| 105 | static CType char_pointer_type, func_old_type, int_type; | ||
| 106 | |||
| 107 | /* use GNU C extensions */ | 26 | /* use GNU C extensions */ |
| 108 | static int gnu_ext = 1; | 27 | ST_DATA int gnu_ext = 1; |
| 109 | 28 | ||
| 110 | /* use Tiny C extensions */ | 29 | /* use TinyCC extensions */ |
| 111 | static int tcc_ext = 1; | 30 | ST_DATA int tcc_ext = 1; |
| 112 | |||
| 113 | /* max number of callers shown if error */ | ||
| 114 | #ifdef CONFIG_TCC_BACKTRACE | ||
| 115 | int num_callers = 6; | ||
| 116 | void *rt_prog_main; | ||
| 117 | const char **rt_bound_error_msg; | ||
| 118 | #endif | ||
| 119 | 31 | ||
| 120 | /* XXX: get rid of this ASAP */ | 32 | /* XXX: get rid of this ASAP */ |
| 121 | static struct TCCState *tcc_state; | 33 | ST_DATA struct TCCState *tcc_state; |
| 122 | |||
| 123 | /********************************************************/ | ||
| 124 | /* function prototypes */ | ||
| 125 | |||
| 126 | /* tccpp.c */ | ||
| 127 | static void next(void); | ||
| 128 | char *get_tok_str(int v, CValue *cv); | ||
| 129 | |||
| 130 | /* tccgen.c */ | ||
| 131 | static void parse_expr_type(CType *type); | ||
| 132 | static void expr_type(CType *type); | ||
| 133 | static void unary_type(CType *type); | ||
| 134 | static void block(int *bsym, int *csym, int *case_sym, int *def_sym, | ||
| 135 | int case_reg, int is_expr); | ||
| 136 | static int expr_const(void); | ||
| 137 | static void expr_eq(void); | ||
| 138 | static void gexpr(void); | ||
| 139 | static void gen_inline_functions(void); | ||
| 140 | static void decl(int l); | ||
| 141 | static void decl_initializer(CType *type, Section *sec, unsigned long c, | ||
| 142 | int first, int size_only); | ||
| 143 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, | ||
| 144 | int has_init, int v, int scope); | ||
| 145 | int gv(int rc); | ||
| 146 | void gv2(int rc1, int rc2); | ||
| 147 | void move_reg(int r, int s); | ||
| 148 | void save_regs(int n); | ||
| 149 | void save_reg(int r); | ||
| 150 | void vpop(void); | ||
| 151 | void vswap(void); | ||
| 152 | void vdup(void); | ||
| 153 | int get_reg(int rc); | ||
| 154 | int get_reg_ex(int rc,int rc2); | ||
| 155 | |||
| 156 | void gen_op(int op); | ||
| 157 | void force_charshort_cast(int t); | ||
| 158 | static void gen_cast(CType *type); | ||
| 159 | void vstore(void); | ||
| 160 | static Sym *sym_find(int v); | ||
| 161 | static Sym *sym_push(int v, CType *type, int r, int c); | ||
| 162 | |||
| 163 | /* type handling */ | ||
| 164 | static int type_size(CType *type, int *a); | ||
| 165 | static inline CType *pointed_type(CType *type); | ||
| 166 | static int pointed_size(CType *type); | ||
| 167 | static int lvalue_type(int t); | ||
| 168 | static int parse_btype(CType *type, AttributeDef *ad); | ||
| 169 | static void type_decl(CType *type, AttributeDef *ad, int *v, int td); | ||
| 170 | static int compare_types(CType *type1, CType *type2, int unqualified); | ||
| 171 | static int is_compatible_types(CType *type1, CType *type2); | ||
| 172 | static int is_compatible_parameter_types(CType *type1, CType *type2); | ||
| 173 | |||
| 174 | int ieee_finite(double d); | ||
| 175 | void vpushi(int v); | ||
| 176 | void vpushll(long long v); | ||
| 177 | void vrott(int n); | ||
| 178 | void vnrott(int n); | ||
| 179 | void lexpand_nr(void); | ||
| 180 | static void vpush_global_sym(CType *type, int v); | ||
| 181 | void vset(CType *type, int r, int v); | ||
| 182 | void type_to_str(char *buf, int buf_size, | ||
| 183 | CType *type, const char *varstr); | ||
| 184 | static Sym *get_sym_ref(CType *type, Section *sec, | ||
| 185 | unsigned long offset, unsigned long size); | ||
| 186 | static Sym *external_global_sym(int v, CType *type, int r); | ||
| 187 | |||
| 188 | /* section generation */ | ||
| 189 | static void section_realloc(Section *sec, unsigned long new_size); | ||
| 190 | static void *section_ptr_add(Section *sec, unsigned long size); | ||
| 191 | static void put_extern_sym(Sym *sym, Section *section, | ||
| 192 | unsigned long value, unsigned long size); | ||
| 193 | static void greloc(Section *s, Sym *sym, unsigned long addr, int type); | ||
| 194 | static int put_elf_str(Section *s, const char *sym); | ||
| 195 | static int put_elf_sym(Section *s, | ||
| 196 | unsigned long value, unsigned long size, | ||
| 197 | int info, int other, int shndx, const char *name); | ||
| 198 | static int add_elf_sym(Section *s, uplong value, unsigned long size, | ||
| 199 | int info, int other, int sh_num, const char *name); | ||
| 200 | static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, | ||
| 201 | int type, int symbol); | ||
| 202 | static void put_stabs(const char *str, int type, int other, int desc, | ||
| 203 | unsigned long value); | ||
| 204 | static void put_stabs_r(const char *str, int type, int other, int desc, | ||
| 205 | unsigned long value, Section *sec, int sym_index); | ||
| 206 | static void put_stabn(int type, int other, int desc, int value); | ||
| 207 | static void put_stabd(int type, int other, int desc); | ||
| 208 | static 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 */ | ||
| 213 | static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); | ||
| 214 | |||
| 215 | /* tcccoff.c */ | ||
| 216 | int tcc_output_coff(TCCState *s1, FILE *f); | ||
| 217 | |||
| 218 | /* tccpe.c */ | ||
| 219 | int pe_load_file(struct TCCState *s1, const char *filename, int fd); | ||
| 220 | int pe_output_file(struct TCCState *s1, const char *filename); | ||
| 221 | int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)); | ||
| 222 | |||
| 223 | /* tccasm.c */ | ||
| 224 | #ifdef CONFIG_TCC_ASM | ||
| 225 | static void asm_expr(TCCState *s1, ExprValue *pe); | ||
| 226 | static int asm_int_expr(TCCState *s1); | ||
| 227 | static int find_constraint(ASMOperand *operands, int nb_operands, | ||
| 228 | const char *name, const char **pp); | ||
| 229 | 34 | ||
| 230 | static int tcc_assemble(TCCState *s1, int do_preprocess); | 35 | #ifdef CONFIG_TCC_BACKTRACE |
| 36 | ST_DATA int num_callers = 6; | ||
| 37 | ST_DATA const char **rt_bound_error_msg; | ||
| 38 | ST_DATA void *rt_prog_main; | ||
| 231 | #endif | 39 | #endif |
| 232 | 40 | ||
| 233 | static void asm_instr(void); | ||
| 234 | static void asm_global_instr(void); | ||
| 235 | |||
| 236 | /********************************************************/ | ||
| 237 | /* libtcc.c */ | ||
| 238 | |||
| 239 | static Sym *__sym_malloc(void); | ||
| 240 | static inline Sym *sym_malloc(void); | ||
| 241 | static inline void sym_free(Sym *sym); | ||
| 242 | Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); | ||
| 243 | static void free_section(Section *s); | ||
| 244 | static void section_realloc(Section *sec, unsigned long new_size); | ||
| 245 | static void *section_ptr_add(Section *sec, unsigned long size); | ||
| 246 | Section *find_section(TCCState *s1, const char *name); | ||
| 247 | static void put_extern_sym2( | ||
| 248 | Sym *sym, Section *section, | ||
| 249 | unsigned long value, unsigned long size, int can_add_underscore); | ||
| 250 | static void put_extern_sym( | ||
| 251 | Sym *sym, Section *section, | ||
| 252 | unsigned long value, unsigned long size); | ||
| 253 | static void greloc(Section *s, Sym *sym, unsigned long offset, int type); | ||
| 254 | |||
| 255 | static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap); | ||
| 256 | static void strcat_printf(char *buf, int buf_size, const char *fmt, ...); | ||
| 257 | |||
| 258 | /* CString handling */ | ||
| 259 | static void cstr_realloc(CString *cstr, int new_size); | ||
| 260 | static inline void cstr_ccat(CString *cstr, int ch); | ||
| 261 | static void cstr_cat(CString *cstr, const char *str); | ||
| 262 | static void cstr_wccat(CString *cstr, int ch); | ||
| 263 | static void cstr_new(CString *cstr); | ||
| 264 | static void cstr_free(CString *cstr); | ||
| 265 | #define cstr_reset(cstr) cstr_free(cstr) | ||
| 266 | static void add_char(CString *cstr, int c); | ||
| 267 | |||
| 268 | static Sym *sym_push2(Sym **ps, int v, int t, long c); | ||
| 269 | static Sym *sym_find2(Sym *s, int v); | ||
| 270 | static inline Sym *struct_find(int v); | ||
| 271 | static inline Sym *sym_find(int v); | ||
| 272 | static Sym *sym_push(int v, CType *type, int r, int c); | ||
| 273 | static Sym *global_identifier_push(int v, int t, int c); | ||
| 274 | static void sym_pop(Sym **ptop, Sym *b); | ||
| 275 | |||
| 276 | BufferedFile *tcc_open(TCCState *s1, const char *filename); | ||
| 277 | void tcc_close(BufferedFile *bf); | ||
| 278 | static int tcc_compile(TCCState *s1); | ||
| 279 | |||
| 280 | void expect(const char *msg); | ||
| 281 | void skip(int c); | ||
| 282 | static void test_lvalue(void); | ||
| 283 | void *resolve_sym(TCCState *s1, const char *sym); | ||
| 284 | |||
| 285 | static inline int isid(int c) | ||
| 286 | { | ||
| 287 | return (c >= 'a' && c <= 'z') | ||
| 288 | || (c >= 'A' && c <= 'Z') | ||
| 289 | || c == '_'; | ||
| 290 | } | ||
| 291 | |||
| 292 | static inline int isnum(int c) | ||
| 293 | { | ||
| 294 | return c >= '0' && c <= '9'; | ||
| 295 | } | ||
| 296 | |||
| 297 | static inline int isoct(int c) | ||
| 298 | { | ||
| 299 | return c >= '0' && c <= '7'; | ||
| 300 | } | ||
| 301 | |||
| 302 | static 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_I386 | 48 | #ifdef TCC_TARGET_I386 |
| 313 | #include "i386-gen.c" | 49 | #include "i386-gen.c" |
| 314 | #endif | 50 | #endif |
| 315 | |||
| 316 | #ifdef TCC_TARGET_ARM | 51 | #ifdef TCC_TARGET_ARM |
| 317 | #include "arm-gen.c" | 52 | #include "arm-gen.c" |
| 318 | #endif | 53 | #endif |
| 319 | |||
| 320 | #ifdef TCC_TARGET_C67 | 54 | #ifdef TCC_TARGET_C67 |
| 321 | #include "c67-gen.c" | 55 | #include "c67-gen.c" |
| 322 | #endif | 56 | #endif |
| 323 | |||
| 324 | #ifdef TCC_TARGET_X86_64 | 57 | #ifdef TCC_TARGET_X86_64 |
| 325 | #include "x86_64-gen.c" | 58 | #include "x86_64-gen.c" |
| 326 | #endif | 59 | #endif |
| 327 | |||
| 328 | #include "tccpp.c" | ||
| 329 | #include "tccgen.c" | ||
| 330 | |||
| 331 | #ifdef CONFIG_TCC_ASM | 60 | #ifdef CONFIG_TCC_ASM |
| 332 | 61 | #include "tccasm.c" | |
| 333 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | 62 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| 334 | #include "i386-asm.c" | 63 | #include "i386-asm.c" |
| 335 | #endif | 64 | #endif |
| 336 | |||
| 337 | #include "tccasm.c" | ||
| 338 | #else | ||
| 339 | static void asm_instr(void) | ||
| 340 | { | ||
| 341 | error("inline asm() not supported"); | ||
| 342 | } | ||
| 343 | static void asm_global_instr(void) | ||
| 344 | { | ||
| 345 | error("inline asm() not supported"); | ||
| 346 | } | ||
| 347 | #endif | 65 | #endif |
| 348 | |||
| 349 | #include "tccelf.c" | ||
| 350 | |||
| 351 | #ifdef TCC_TARGET_COFF | 66 | #ifdef TCC_TARGET_COFF |
| 352 | #include "tcccoff.c" | 67 | #include "tcccoff.c" |
| 353 | #endif | 68 | #endif |
| 354 | |||
| 355 | #ifdef TCC_TARGET_PE | 69 | #ifdef TCC_TARGET_PE |
| 356 | #include "tccpe.c" | 70 | #include "tccpe.c" |
| 357 | #endif | 71 | #endif |
| 72 | #endif /* ALL_IN_ONE */ | ||
| 358 | 73 | ||
| 359 | #include "tccrun.c" | 74 | /********************************************************/ |
| 75 | #ifndef CONFIG_TCC_ASM | ||
| 76 | ST_FUNC void asm_instr(void) | ||
| 77 | { | ||
| 78 | error("inline asm() not supported"); | ||
| 79 | } | ||
| 80 | ST_FUNC void asm_global_instr(void) | ||
| 81 | { | ||
| 82 | error("inline asm() not supported"); | ||
| 83 | } | ||
| 84 | #endif | ||
| 360 | 85 | ||
| 361 | /********************************************************/ | 86 | /********************************************************/ |
| 87 | |||
| 362 | #ifdef _WIN32 | 88 | #ifdef _WIN32 |
| 363 | char *normalize_slashes(char *path) | 89 | static 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 | ||
| 372 | HMODULE tcc_module; | 98 | static 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' */ |
| 375 | void tcc_set_lib_path_w32(TCCState *s) | 101 | static 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 | #endif | 122 | #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 */ | ||
| 403 | int 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. */ |
| 410 | char *pstrcpy(char *buf, int buf_size, const char *s) | 126 | PUB_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. */ |
| 430 | char *pstrcat(char *buf, int buf_size, const char *s) | 146 | PUB_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 */ |
| 440 | char *tcc_basename(const char *name) | 156 | PUB_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 | ||
| 448 | char *tcc_fileextension (const char *name) | 164 | PUB_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_DEBUG | 178 | #ifdef MEM_DEBUG |
| 457 | int mem_cur_size; | 179 | int mem_cur_size; |
| 458 | int mem_max_size; | 180 | int mem_max_size; |
| 459 | unsigned malloc_usable_size(void*); | 181 | unsigned malloc_usable_size(void*); |
| 460 | #endif | 182 | #endif |
| 461 | 183 | ||
| 462 | void tcc_free(void *ptr) | 184 | PUB_FUNC void tcc_free(void *ptr) |
| 463 | { | 185 | { |
| 464 | #ifdef MEM_DEBUG | 186 | #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 | ||
| 470 | void *tcc_malloc(unsigned long size) | 192 | PUB_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 | ||
| 484 | void *tcc_mallocz(unsigned long size) | 206 | PUB_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 | ||
| 492 | void *tcc_realloc(void *ptr, unsigned long size) | 214 | PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) |
| 493 | { | 215 | { |
| 494 | void *ptr1; | 216 | void *ptr1; |
| 495 | #ifdef MEM_DEBUG | 217 | #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 | ||
| 508 | char *tcc_strdup(const char *str) | 230 | PUB_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 | ||
| 516 | void tcc_memstats(void) | 238 | PUB_FUNC void tcc_memstats(void) |
| 517 | { | 239 | { |
| 518 | #ifdef MEM_DEBUG | 240 | #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 | ||
| 527 | void dynarray_add(void ***ptab, int *nb_ptr, void *data) | 249 | /********************************************************/ |
| 250 | /* dynarrays */ | ||
| 251 | |||
| 252 | PUB_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 | ||
| 549 | void dynarray_reset(void *pp, int *n) | 274 | PUB_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 |
| 560 | static Sym *__sym_malloc(void) | 285 | non standard math libs */ |
| 561 | { | 286 | /* XXX: endianness dependent */ |
| 562 | Sym *sym_pool, *sym, *last_sym; | 287 | ST_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 | |||
| 579 | static 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 | ||
| 589 | static inline void sym_free(Sym *sym) | 293 | /********************************************************/ |
| 590 | { | ||
| 591 | sym->next = sym_free_first; | ||
| 592 | sym_free_first = sym; | ||
| 593 | } | ||
| 594 | 294 | ||
| 595 | Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) | 295 | ST_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 */ |
| 636 | static void section_realloc(Section *sec, unsigned long new_size) | 336 | ST_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' from | 354 | /* reserve at least 'size' bytes in section 'sec' from |
| 655 | sec->data_offset. */ | 355 | sec->data_offset. */ |
| 656 | static void *section_ptr_add(Section *sec, unsigned long size) | 356 | ST_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 not | 368 | /* return a reference to a section, and create it if it does not |
| 669 | exists */ | 369 | exists */ |
| 670 | Section *find_section(TCCState *s1, const char *name) | 370 | ST_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 section | 383 | /* update sym->c so that it points to an external symbol in section |
| 684 | 'section' with value 'value' */ | 384 | 'section' with value 'value' */ |
| 685 | static void put_extern_sym2(Sym *sym, Section *section, | 385 | ST_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 | ||
| 782 | static void put_extern_sym(Sym *sym, Section *section, | 482 | ST_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' */ |
| 789 | static void greloc(Section *s, Sym *sym, unsigned long offset, int type) | 489 | ST_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 | |||
| 801 | static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) | 503 | static 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 | ||
| 816 | void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) | 518 | static 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 | ||
| 853 | void tcc_set_error_func(TCCState *s, void *error_opaque, | 555 | LIBTCCAPI 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 */ |
| 861 | void error_noabort(const char *fmt, ...) | 563 | PUB_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 | ||
| 871 | void error(const char *fmt, ...) | 573 | PUB_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 | ||
| 888 | void expect(const char *msg) | 590 | PUB_FUNC void expect(const char *msg) |
| 889 | { | 591 | { |
| 890 | error("%s expected", msg); | 592 | error("%s expected", msg); |
| 891 | } | 593 | } |
| 892 | 594 | ||
| 893 | void warning(const char *fmt, ...) | 595 | PUB_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 | ||
| 906 | void skip(int c) | 608 | /********************************************************/ |
| 907 | { | ||
| 908 | if (tok != c) | ||
| 909 | error("'%c' expected", c); | ||
| 910 | next(); | ||
| 911 | } | ||
| 912 | |||
| 913 | static void test_lvalue(void) | ||
| 914 | { | ||
| 915 | if (!(vtop->r & VT_LVAL)) | ||
| 916 | expect("lvalue"); | ||
| 917 | } | ||
| 918 | |||
| 919 | /* CString handling */ | ||
| 920 | |||
| 921 | static 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 */ | ||
| 940 | static 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 | |||
| 950 | static 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 */ | ||
| 963 | static 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 | |||
| 973 | static void cstr_new(CString *cstr) | ||
| 974 | { | ||
| 975 | memset(cstr, 0, sizeof(CString)); | ||
| 976 | } | ||
| 977 | |||
| 978 | /* free string and reset it to NULL */ | ||
| 979 | static 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 ? */ | ||
| 988 | static 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 */ | ||
| 1009 | static 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 */ | ||
| 1029 | static 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 */ | ||
| 1040 | static 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 */ | ||
| 1049 | static 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 */ | ||
| 1058 | static 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 */ | ||
| 1086 | static 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' */ | ||
| 1104 | static 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 | ||
| 1132 | BufferedFile *tcc_open(TCCState *s1, const char *filename) | 611 | ST_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 | ||
| 1162 | void tcc_close(BufferedFile *bf) | 641 | ST_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 | ||
| 1275 | int tcc_compile_string(TCCState *s, const char *str) | 754 | LIBTCCAPI 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 */ |
| 1304 | void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) | 783 | LIBTCCAPI 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 */ |
| 1334 | void tcc_undefine_symbol(TCCState *s1, const char *sym) | 813 | LIBTCCAPI 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 | ||
| 1372 | TCCState *tcc_new(void) | 851 | LIBTCCAPI 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_UNSIGNED | 961 | #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 | #endif | 967 | #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_I386 | 970 | #ifdef TCC_TARGET_I386 |
| 1493 | s->seg_size = 32; | 971 | s->seg_size = 32; |
| 1494 | #endif | 972 | #endif |
| 1495 | return s; | 973 | return s; |
| 1496 | } | 974 | } |
| 1497 | 975 | ||
| 1498 | void tcc_delete(TCCState *s1) | 976 | LIBTCCAPI 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 | ||
| 1536 | int tcc_add_include_path(TCCState *s1, const char *pathname) | 1014 | LIBTCCAPI 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 | ||
| 1545 | int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) | 1023 | LIBTCCAPI 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 | ||
| 1671 | int tcc_add_file(TCCState *s, const char *filename) | 1149 | LIBTCCAPI 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 | ||
| 1679 | int tcc_add_library_path(TCCState *s, const char *pathname) | 1157 | LIBTCCAPI 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 ? */ |
| 1690 | static int tcc_add_dll(TCCState *s, const char *filename, int flags) | 1168 | ST_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 */ |
| 1705 | int tcc_add_library(TCCState *s, const char *libraryname) | 1183 | LIBTCCAPI 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 | ||
| 1731 | int tcc_add_symbol(TCCState *s, const char *name, void *val) | 1209 | LIBTCCAPI 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 | ||
| 1739 | int tcc_set_output_type(TCCState *s, int output_type) | 1217 | LIBTCCAPI 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 | ||
| 1828 | static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, | 1306 | ST_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 */ |
| 1854 | int tcc_set_warning(TCCState *s, const char *warning_name, int value) | 1331 | LIBTCCAPI 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 */ |
| 1879 | int tcc_set_flag(TCCState *s, const char *flag_name, int value) | 1356 | PUB_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 */ | 1362 | PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) |
| 1886 | void 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 | |||
| 1892 | void 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 */ | ||
| 1377 | LIBTCCAPI 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 | |||
| 1383 | PUB_FUNC void set_num_callers(int n) | ||
| 1384 | { | ||
| 1385 | #ifdef CONFIG_TCC_BACKTRACE | ||
| 1386 | num_callers = n; | ||
| 1387 | #endif | ||
| 1388 | } | ||
| @@ -18,13 +18,25 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #ifdef TCC_USE_LIBTCC | 21 | #if defined NOTALLINONE || defined TCC_USE_LIBTCC |
| 22 | #include "tcc.h" | 22 | #include "tcc.h" |
| 23 | #else | 23 | #else |
| 24 | #include "libtcc.c" | 24 | #include "libtcc.c" |
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | void help(void) | 27 | static char **files; |
| 28 | static int nb_files, nb_libraries; | ||
| 29 | static int multiple_files; | ||
| 30 | static int print_search_dirs; | ||
| 31 | static int output_type; | ||
| 32 | static int reloc_output; | ||
| 33 | static const char *outfile; | ||
| 34 | static 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 | |||
| 39 | static 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 | ||
| 68 | static char **files; | ||
| 69 | static int nb_files, nb_libraries; | ||
| 70 | static int multiple_files; | ||
| 71 | static int print_search_dirs; | ||
| 72 | static int output_type; | ||
| 73 | static int reloc_output; | ||
| 74 | static const char *outfile; | ||
| 75 | static 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 | |||
| 80 | typedef struct TCCOption { | 80 | typedef 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 | ||
| 216 | int parse_args(TCCState *s, int argc, char **argv) | 216 | static 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_BACKTRACE | 305 | #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 | #endif | 309 | #endif |
| 310 | #ifdef CONFIG_TCC_BCHECK | 310 | #ifdef CONFIG_TCC_BCHECK |
| @@ -18,6 +18,9 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * 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_SOURCE | 24 | #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 __inline | 50 | #define inline __inline |
| 48 | #define inp next_inp | 51 | #define inp next_inp |
| 52 | #define dlclose FreeLibrary | ||
| 49 | #ifdef _WIN64 | 53 | #ifdef _WIN64 |
| 50 | #define uplong unsigned long long | 54 | #define uplong unsigned long long |
| 51 | #endif | 55 | #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 | #endif | 64 | #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 */ |
| 769 | long double strtold(const char *nptr, char **endptr) | 774 | static 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 | } |
| 773 | float strtof(const char *nptr, char **endptr) | 778 | static 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 strcmp | 795 | #define PATHCMP strcmp |
| 791 | #endif | 796 | #endif |
| 792 | 797 | ||
| 793 | void error(const char *fmt, ...); | 798 | /* space exlcuding newline */ |
| 794 | void error_noabort(const char *fmt, ...); | 799 | static inline int is_space(int ch) |
| 795 | void warning(const char *fmt, ...); | 800 | { |
| 796 | 801 | return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; | |
| 797 | void tcc_set_lib_path_w32(TCCState *s); | 802 | } |
| 798 | int tcc_set_flag(TCCState *s, const char *flag_name, int value); | ||
| 799 | void tcc_print_stats(TCCState *s, int64_t total_time); | ||
| 800 | 803 | ||
| 801 | void tcc_free(void *ptr); | 804 | static inline int isid(int c) |
| 802 | void *tcc_malloc(unsigned long size); | 805 | { |
| 803 | void *tcc_mallocz(unsigned long size); | 806 | return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; |
| 804 | void *tcc_realloc(void *ptr, unsigned long size); | 807 | } |
| 805 | char *tcc_strdup(const char *str); | ||
| 806 | 808 | ||
| 807 | char *tcc_basename(const char *name); | 809 | static inline int isnum(int c) |
| 808 | char *tcc_fileextension (const char *name); | 810 | { |
| 809 | char *pstrcpy(char *buf, int buf_size, const char *s); | 811 | return c >= '0' && c <= '9'; |
| 810 | char *pstrcat(char *buf, int buf_size, const char *s); | 812 | } |
| 811 | void dynarray_add(void ***ptab, int *nb_ptr, void *data); | ||
| 812 | void dynarray_reset(void *pp, int *n); | ||
| 813 | 813 | ||
| 814 | /* true if float/double/long double type */ | 814 | static inline int isoct(int c) |
| 815 | static 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 */ | 819 | static inline int toup(int c) |
| 823 | static 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 */ | ||
| 839 | ST_DATA int gnu_ext; | ||
| 840 | /* use Tiny C extensions */ | ||
| 841 | ST_DATA int tcc_ext; | ||
| 842 | /* XXX: get rid of this ASAP */ | ||
| 843 | ST_DATA struct TCCState *tcc_state; | ||
| 844 | |||
| 845 | #ifdef CONFIG_TCC_BACKTRACE | ||
| 846 | ST_DATA int num_callers; | ||
| 847 | ST_DATA const char **rt_bound_error_msg; | ||
| 848 | ST_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 */ | ||
| 856 | PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s); | ||
| 857 | PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s); | ||
| 858 | PUB_FUNC char *tcc_basename(const char *name); | ||
| 859 | PUB_FUNC char *tcc_fileextension (const char *name); | ||
| 860 | PUB_FUNC void tcc_free(void *ptr); | ||
| 861 | PUB_FUNC void *tcc_malloc(unsigned long size); | ||
| 862 | PUB_FUNC void *tcc_mallocz(unsigned long size); | ||
| 863 | PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size); | ||
| 864 | PUB_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) | ||
| 870 | PUB_FUNC void tcc_memstats(void); | ||
| 871 | PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data); | ||
| 872 | PUB_FUNC void dynarray_reset(void *pp, int *n); | ||
| 873 | PUB_FUNC void error_noabort(const char *fmt, ...); | ||
| 874 | PUB_FUNC void error(const char *fmt, ...); | ||
| 875 | PUB_FUNC void expect(const char *msg); | ||
| 876 | PUB_FUNC void warning(const char *fmt, ...); | ||
| 877 | |||
| 878 | /* other utilities */ | ||
| 879 | ST_INLN void cstr_ccat(CString *cstr, int ch); | ||
| 880 | ST_FUNC void cstr_cat(CString *cstr, const char *str); | ||
| 881 | ST_FUNC void cstr_wccat(CString *cstr, int ch); | ||
| 882 | ST_FUNC void cstr_new(CString *cstr); | ||
| 883 | ST_FUNC void cstr_free(CString *cstr); | ||
| 884 | ST_FUNC void add_char(CString *cstr, int c); | ||
| 885 | #define cstr_reset(cstr) cstr_free(cstr) | ||
| 886 | |||
| 887 | ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); | ||
| 888 | ST_FUNC void section_realloc(Section *sec, unsigned long new_size); | ||
| 889 | ST_FUNC void *section_ptr_add(Section *sec, unsigned long size); | ||
| 890 | ST_FUNC Section *find_section(TCCState *s1, const char *name); | ||
| 891 | |||
| 892 | ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore); | ||
| 893 | ST_FUNC void put_extern_sym(Sym *sym, Section *section, unsigned long value, unsigned long size); | ||
| 894 | ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); | ||
| 895 | |||
| 896 | ST_INLN void sym_free(Sym *sym); | ||
| 897 | ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c); | ||
| 898 | ST_FUNC Sym *sym_find2(Sym *s, int v); | ||
| 899 | ST_FUNC Sym *sym_push(int v, CType *type, int r, int c); | ||
| 900 | ST_FUNC void sym_pop(Sym **ptop, Sym *b); | ||
| 901 | ST_INLN Sym *struct_find(int v); | ||
| 902 | ST_INLN Sym *sym_find(int v); | ||
| 903 | ST_FUNC Sym *global_identifier_push(int v, int t, int c); | ||
| 904 | |||
| 905 | ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename); | ||
| 906 | ST_FUNC void tcc_close(BufferedFile *bf); | ||
| 907 | ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); | ||
| 908 | PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value); | ||
| 909 | PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); | ||
| 910 | PUB_FUNC void set_num_callers(int n); | ||
| 911 | |||
| 912 | ST_FUNC int ieee_finite(double d); | ||
| 913 | |||
| 914 | /* ------------ tccpp.c ------------ */ | ||
| 915 | |||
| 916 | ST_DATA struct BufferedFile *file; | ||
| 917 | ST_DATA int ch, tok; | ||
| 918 | ST_DATA CValue tokc; | ||
| 919 | ST_DATA int *macro_ptr; | ||
| 920 | ST_DATA int parse_flags; | ||
| 921 | ST_DATA int tok_flags; | ||
| 922 | ST_DATA CString tokcstr; /* current parsed string, if any */ | ||
| 923 | |||
| 924 | /* display benchmark infos */ | ||
| 925 | ST_DATA int total_lines; | ||
| 926 | ST_DATA int total_bytes; | ||
| 927 | ST_DATA int tok_ident; | ||
| 928 | ST_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 | |||
| 943 | ST_FUNC TokenSym *tok_alloc(const char *str, int len); | ||
| 944 | ST_FUNC char *get_tok_str(int v, CValue *cv); | ||
| 945 | ST_FUNC void save_parse_state(ParseState *s); | ||
| 946 | ST_FUNC void restore_parse_state(ParseState *s); | ||
| 947 | ST_INLN void tok_str_new(TokenString *s); | ||
| 948 | ST_FUNC void tok_str_free(int *str); | ||
| 949 | ST_FUNC void tok_str_add(TokenString *s, int t); | ||
| 950 | ST_FUNC void tok_str_add_tok(TokenString *s); | ||
| 951 | ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg); | ||
| 952 | ST_FUNC void define_undef(Sym *s); | ||
| 953 | ST_INLN Sym *define_find(int v); | ||
| 954 | ST_FUNC void free_defines(Sym *b); | ||
| 955 | ST_FUNC Sym *label_find(int v); | ||
| 956 | ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); | ||
| 957 | ST_FUNC void label_pop(Sym **ptop, Sym *slast); | ||
| 958 | ST_FUNC void parse_define(void); | ||
| 959 | ST_FUNC void preprocess(int is_bof); | ||
| 960 | ST_FUNC void next_nomacro(void); | ||
| 961 | ST_FUNC void next(void); | ||
| 962 | ST_INLN void unget_tok(int last_tok); | ||
| 963 | ST_FUNC void preprocess_init(TCCState *s1); | ||
| 964 | ST_FUNC void preprocess_new(); | ||
| 965 | ST_FUNC int tcc_preprocess(TCCState *s1); | ||
| 966 | ST_FUNC void skip(int c); | ||
| 967 | |||
| 968 | /* ------------ tccgen.c ------------ */ | ||
| 969 | |||
| 970 | ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ | ||
| 971 | ST_DATA Section *cur_text_section; /* current section where function code is generated */ | ||
| 972 | #ifdef CONFIG_TCC_ASM | ||
| 973 | ST_DATA Section *last_text_section; /* to handle .previous asm directive */ | ||
| 974 | #endif | ||
| 975 | #ifdef CONFIG_TCC_BCHECK | ||
| 976 | /* bound check related sections */ | ||
| 977 | ST_DATA Section *bounds_section; /* contains global data bound description */ | ||
| 978 | ST_DATA Section *lbounds_section; /* contains local data bound description */ | ||
| 979 | #endif | ||
| 980 | /* symbol sections */ | ||
| 981 | ST_DATA Section *symtab_section, *strtab_section; | ||
| 982 | /* debug sections */ | ||
| 983 | ST_DATA Section *stab_section, *stabstr_section; | ||
| 984 | |||
| 985 | #define SYM_POOL_NB (8192 / sizeof(Sym)) | ||
| 986 | ST_DATA Sym *sym_free_first; | ||
| 987 | ST_DATA void **sym_pools; | ||
| 988 | ST_DATA int nb_sym_pools; | ||
| 989 | |||
| 990 | ST_DATA Sym *global_stack; | ||
| 991 | ST_DATA Sym *local_stack; | ||
| 992 | ST_DATA Sym *local_label_stack; | ||
| 993 | ST_DATA Sym *global_label_stack; | ||
| 994 | ST_DATA Sym *define_stack; | ||
| 995 | ST_DATA CType char_pointer_type, func_old_type, int_type; | ||
| 996 | ST_DATA SValue vstack[VSTACK_SIZE], *vtop; | ||
| 997 | ST_DATA int rsym, anon_sym, ind, loc; | ||
| 998 | |||
| 999 | ST_DATA int const_wanted; /* true if constant wanted */ | ||
| 1000 | ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ | ||
| 1001 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | ||
| 1002 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ | ||
| 1003 | ST_DATA int func_vc; | ||
| 1004 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ | ||
| 1005 | ST_DATA char *funcname; | ||
| 1006 | |||
| 1007 | ST_INLN int is_float(int t); | ||
| 1008 | ST_FUNC void test_lvalue(void); | ||
| 1009 | ST_FUNC void swap(int *p, int *q); | ||
| 1010 | ST_FUNC void vpushi(int v); | ||
| 1011 | ST_FUNC Sym *external_global_sym(int v, CType *type, int r); | ||
| 1012 | ST_FUNC void vset(CType *type, int r, int v); | ||
| 1013 | ST_FUNC void vswap(void); | ||
| 1014 | ST_FUNC void save_reg(int r); | ||
| 1015 | ST_FUNC int get_reg(int rc); | ||
| 1016 | ST_FUNC void save_regs(int n); | ||
| 1017 | ST_FUNC int gv(int rc); | ||
| 1018 | ST_FUNC void gv2(int rc1, int rc2); | ||
| 1019 | ST_FUNC void vpop(void); | ||
| 1020 | ST_FUNC void gen_op(int op); | ||
| 1021 | ST_FUNC int type_size(CType *type, int *a); | ||
| 1022 | ST_FUNC void mk_pointer(CType *type); | ||
| 1023 | ST_FUNC void vstore(void); | ||
| 1024 | ST_FUNC void inc(int post, int c); | ||
| 1025 | ST_FUNC int lvalue_type(int t); | ||
| 1026 | ST_FUNC void indir(void); | ||
| 1027 | ST_FUNC void unary(void); | ||
| 1028 | ST_FUNC void expr_prod(void); | ||
| 1029 | ST_FUNC void expr_sum(void); | ||
| 1030 | ST_FUNC void gexpr(void); | ||
| 1031 | ST_FUNC int expr_const(void); | ||
| 1032 | ST_FUNC void gen_inline_functions(void); | ||
| 1033 | ST_FUNC void decl(int l); | ||
| 1034 | #ifdef CONFIG_TCC_BCHECK | ||
| 1035 | ST_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 | |||
| 1042 | typedef 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 | |||
| 1050 | ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); | ||
| 1051 | |||
| 1052 | ST_FUNC int put_elf_str(Section *s, const char *sym); | ||
| 1053 | ST_FUNC int put_elf_sym(Section *s, unsigned long value, unsigned long size, int info, int other, int shndx, const char *name); | ||
| 1054 | ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, int info, int other, int sh_num, const char *name); | ||
| 1055 | ST_FUNC int find_elf_sym(Section *s, const char *name); | ||
| 1056 | ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); | ||
| 1057 | |||
| 1058 | ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value); | ||
| 1059 | ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index); | ||
| 1060 | ST_FUNC void put_stabn(int type, int other, int desc, int value); | ||
| 1061 | ST_FUNC void put_stabd(int type, int other, int desc); | ||
| 1062 | |||
| 1063 | ST_FUNC void relocate_common_syms(void); | ||
| 1064 | ST_FUNC void relocate_syms(TCCState *s1, int do_resolve); | ||
| 1065 | ST_FUNC void relocate_section(TCCState *s1, Section *s); | ||
| 1066 | |||
| 1067 | ST_FUNC void tcc_add_linker_symbols(TCCState *s1); | ||
| 1068 | ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); | ||
| 1069 | ST_FUNC int tcc_load_archive(TCCState *s1, int fd); | ||
| 1070 | ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name); | ||
| 1071 | ST_FUNC void tcc_add_bcheck(TCCState *s1); | ||
| 1072 | |||
| 1073 | ST_FUNC void build_got_entries(TCCState *s1); | ||
| 1074 | ST_FUNC void tcc_add_runtime(TCCState *s1); | ||
| 1075 | |||
| 1076 | #ifndef TCC_TARGET_PE | ||
| 1077 | ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level); | ||
| 1078 | ST_FUNC int tcc_load_ldscript(TCCState *s1); | ||
| 1079 | ST_FUNC uint8_t *parse_comment(uint8_t *p); | ||
| 1080 | ST_FUNC void minp(void); | ||
| 1081 | ST_INLN void inp(void); | ||
| 1082 | ST_FUNC int handle_eob(void); | ||
| 1083 | #endif | ||
| 1084 | |||
| 1085 | /* ------------ xxx-gen.c ------------ */ | ||
| 1086 | |||
| 1087 | ST_FUNC void gsym_addr(int t, int a); | ||
| 1088 | ST_FUNC void gsym(int t); | ||
| 1089 | ST_FUNC void load(int r, SValue *sv); | ||
| 1090 | ST_FUNC void store(int r, SValue *v); | ||
| 1091 | ST_FUNC void gfunc_call(int nb_args); | ||
| 1092 | ST_FUNC void gfunc_prolog(CType *func_type); | ||
| 1093 | ST_FUNC void gfunc_epilog(void); | ||
| 1094 | ST_FUNC int gjmp(int t); | ||
| 1095 | ST_FUNC void gjmp_addr(int a); | ||
| 1096 | ST_FUNC int gtst(int inv, int t); | ||
| 1097 | ST_FUNC void gen_opi(int op); | ||
| 1098 | ST_FUNC void gen_opf(int op); | ||
| 1099 | ST_FUNC void gen_cvt_ftoi(int t); | ||
| 1100 | ST_FUNC void gen_cvt_ftof(int t); | ||
| 1101 | ST_FUNC void ggoto(void); | ||
| 1102 | #ifndef TCC_TARGET_C67 | ||
| 1103 | ST_FUNC void o(unsigned int c); | ||
| 1104 | #endif | ||
| 1105 | #ifndef TCC_TARGET_ARM | ||
| 1106 | ST_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 | ||
| 1111 | ST_FUNC void g(int c); | ||
| 1112 | ST_FUNC int oad(int c, int s); | ||
| 1113 | ST_FUNC void gen_le16(int c); | ||
| 1114 | ST_FUNC void gen_le32(int c); | ||
| 1115 | ST_FUNC void gen_addr32(int r, Sym *sym, int c); | ||
| 1116 | ST_FUNC void gen_addrpc32(int r, Sym *sym, int c); | ||
| 1117 | #endif | ||
| 1118 | |||
| 1119 | #ifdef CONFIG_TCC_BCHECK | ||
| 1120 | ST_FUNC void gen_bounded_ptr_add(void); | ||
| 1121 | ST_FUNC void gen_bounded_ptr_deref(void); | ||
| 1122 | #endif | ||
| 1123 | |||
| 1124 | /* ------------ x86_64-gen.c ------------ */ | ||
| 1125 | #ifdef TCC_TARGET_X86_64 | ||
| 1126 | ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); | ||
| 1127 | #endif | ||
| 1128 | |||
| 1129 | /* ------------ arm-gen.c ------------ */ | ||
| 1130 | #ifdef TCC_TARGET_ARM | ||
| 1131 | ST_FUNC unsigned long encbranch(int pos,int addr,int fail); | ||
| 1132 | ST_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 | ||
| 1142 | ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f); | ||
| 1143 | #endif | ||
| 1144 | |||
| 1145 | /* ------------ tccasm.c ------------ */ | ||
| 1146 | ST_FUNC void asm_instr(void); | ||
| 1147 | ST_FUNC void asm_global_instr(void); | ||
| 1148 | |||
| 1149 | #ifdef CONFIG_TCC_ASM | ||
| 1150 | ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp); | ||
| 1151 | ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); | ||
| 1152 | ST_FUNC int asm_int_expr(TCCState *s1); | ||
| 1153 | ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess); | ||
| 1154 | /* ------------ i386-asm.c ------------ */ | ||
| 1155 | ST_FUNC void gen_expr32(ExprValue *pe); | ||
| 1156 | ST_FUNC void asm_opcode(TCCState *s1, int opcode); | ||
| 1157 | ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg); | ||
| 1158 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); | ||
| 1159 | ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg); | ||
| 1160 | ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); | ||
| 1161 | #endif | ||
| 1162 | /* ------------ tccpe.c -------------- */ | ||
| 1163 | #ifdef TCC_TARGET_PE | ||
| 1164 | ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); | ||
| 1165 | ST_FUNC int pe_add_dll(struct TCCState *s, const char *libraryname); | ||
| 1166 | ST_FUNC int pe_output_file(TCCState * s1, const char *filename); | ||
| 1167 | ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)); | ||
| 1168 | /* tiny_impdef.c */ | ||
| 1169 | ST_FUNC char *get_export_names(FILE *fp); | ||
| 1170 | #endif | ||
| 1171 | |||
| 1172 | /* ------------ tccrun.c ----------------- */ | ||
| 1173 | #if !defined CONFIG_TCC_STATIC && !defined _WIN32 | ||
| 1174 | ST_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 | |||
| 1195 | ST_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 */ | ||
| @@ -18,7 +18,9 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | static int asm_get_local_label_name(TCCState *s1, unsigned int n) | 21 | #include "tcc.h" |
| 22 | |||
| 23 | ST_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 | ||
| 31 | static void asm_expr(TCCState *s1, ExprValue *pe); | 33 | ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); |
| 32 | 34 | ||
| 33 | /* We do not use the C expression parser to handle symbols. Maybe the | 35 | /* 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 | ||
| 241 | static void asm_expr(TCCState *s1, ExprValue *pe) | 243 | ST_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 | ||
| 246 | static int asm_int_expr(TCCState *s1) | 248 | ST_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 */ |
| 702 | static int tcc_assemble(TCCState *s1, int do_preprocess) | 704 | ST_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 extended | 767 | /* find a constraint by its number or id (gcc 3 extended |
| 766 | syntax). return -1 if not found. Return in *pp in char after the | 768 | syntax). return -1 if not found. Return in *pp in char after the |
| 767 | constraint */ | 769 | constraint */ |
| 768 | static int find_constraint(ASMOperand *operands, int nb_operands, | 770 | ST_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 */ |
| 919 | static void asm_instr(void) | 921 | ST_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 | ||
| 1020 | static void asm_global_instr(void) | 1022 | ST_FUNC void asm_global_instr(void) |
| 1021 | { | 1023 | { |
| 1022 | CString astr; | 1024 | CString astr; |
| 1023 | 1025 | ||
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | * License along with this library; if not, write to the Free Software | 18 | * License along with this library; if not, write to the Free Software |
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * 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 | ||
| 76 | int tcc_output_coff(TCCState *s1, FILE *f) | 78 | ST_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; |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * 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_64 | 23 | #ifdef TCC_TARGET_X86_64 |
| 22 | #define ElfW_Rel ElfW(Rela) | 24 | #define ElfW_Rel ElfW(Rela) |
| 23 | #define SHT_RELX SHT_RELA | 25 | #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_PLT | 36 | //#define TCC_OUTPUT_DLL_WITH_PLT |
| 35 | 37 | ||
| 36 | static int put_elf_str(Section *s, const char *sym) | 38 | ST_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 */ |
| 98 | static int put_elf_sym(Section *s, | 100 | ST_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 not | 148 | /* find global ELF symbol 'name' and return its index. Return 0 if not |
| 147 | found. */ | 149 | found. */ |
| 148 | static int find_elf_sym(Section *s, const char *name) | 150 | ST_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 */ |
| 188 | void *tcc_get_symbol(TCCState *s, const char *name) | 190 | LIBTCCAPI 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 */ |
| 194 | void *tcc_get_symbol_err(TCCState *s, const char *name) | 196 | ST_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 patch | 201 | /* 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. */ |
| 201 | static int add_elf_sym(Section *s, uplong value, unsigned long size, | 203 | ST_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 */ |
| 275 | static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, | 277 | ST_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 | ||
| 304 | typedef struct { | 306 | ST_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 | |||
| 312 | static 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 | ||
| 329 | static void put_stabs_r(const char *str, int type, int other, int desc, | 323 | ST_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 | ||
| 338 | static void put_stabn(int type, int other, int desc, int value) | 332 | ST_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 | ||
| 343 | static void put_stabd(int type, int other, int desc) | 337 | ST_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 */ |
| 413 | static void relocate_common_syms(void) | 407 | ST_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 is | 429 | /* 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. */ |
| 437 | static void relocate_syms(TCCState *s1, int do_resolve) | 431 | ST_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 | #endif | 507 | #endif |
| 514 | 508 | ||
| 515 | /* relocate a given section (CPU dependent) */ | 509 | /* relocate a given section (CPU dependent) */ |
| 516 | static void relocate_section(TCCState *s1, Section *s) | 510 | ST_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 */ |
| 1015 | static void build_got_entries(TCCState *s1) | 1009 | ST_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 | ||
| 1123 | static Section *new_symtab(TCCState *s1, | 1117 | ST_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 | ||
| 1189 | static void tcc_add_bcheck(TCCState *s1) | 1183 | ST_FUNC void tcc_add_bcheck(TCCState *s1) |
| 1190 | { | 1184 | { |
| 1191 | #ifdef CONFIG_TCC_BCHECK | 1185 | #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 */ |
| 1230 | static void tcc_add_runtime(TCCState *s1) | 1224 | ST_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 the | 1246 | /* add various standard linker symbols (must be done after the |
| 1253 | sections are filled (for example after allocating common | 1247 | sections are filled (for example after allocating common |
| 1254 | symbols)) */ | 1248 | symbols)) */ |
| 1255 | static void tcc_add_linker_symbols(TCCState *s1) | 1249 | ST_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 */ |
| 1374 | int elf_output_file(TCCState *s1, const char *filename) | 1368 | static 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 | ||
| 2113 | int tcc_output_file(TCCState *s, const char *filename) | 2107 | LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename) |
| 2114 | { | 2108 | { |
| 2115 | int ret; | 2109 | int ret; |
| 2116 | #ifdef TCC_TARGET_PE | 2110 | #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 */ |
| 2146 | static int tcc_load_object_file(TCCState *s1, | 2140 | ST_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 | |||
| 2417 | typedef struct ArchiveHeader { | 2409 | typedef 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 */ |
| 2477 | static int tcc_load_archive(TCCState *s1, int fd) | 2469 | ST_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 DLL | 2521 | /* 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 in | 2522 | is referenced by the user (so it should be added as DT_NEEDED in |
| 2531 | the generated ELF file) */ | 2523 | the generated ELF file) */ |
| 2532 | static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) | 2524 | ST_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.so | 2795 | /* interpret a subset of GNU ldscripts to handle the dummy libc.so |
| 2804 | files */ | 2796 | files */ |
| 2805 | static int tcc_load_ldscript(TCCState *s1) | 2797 | ST_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]; |
| @@ -18,7 +18,244 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | void 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 | */ | ||
| 31 | ST_DATA int rsym, anon_sym, ind, loc; | ||
| 32 | |||
| 33 | ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ | ||
| 34 | ST_DATA Section *cur_text_section; /* current section where function code is generated */ | ||
| 35 | #ifdef CONFIG_TCC_ASM | ||
| 36 | ST_DATA Section *last_text_section; /* to handle .previous asm directive */ | ||
| 37 | #endif | ||
| 38 | #ifdef CONFIG_TCC_BCHECK | ||
| 39 | /* bound check related sections */ | ||
| 40 | ST_DATA Section *bounds_section; /* contains global data bound description */ | ||
| 41 | ST_DATA Section *lbounds_section; /* contains local data bound description */ | ||
| 42 | #endif | ||
| 43 | /* symbol sections */ | ||
| 44 | ST_DATA Section *symtab_section, *strtab_section; | ||
| 45 | /* debug sections */ | ||
| 46 | ST_DATA Section *stab_section, *stabstr_section; | ||
| 47 | ST_DATA Sym *sym_free_first; | ||
| 48 | ST_DATA void **sym_pools; | ||
| 49 | ST_DATA int nb_sym_pools; | ||
| 50 | |||
| 51 | ST_DATA Sym *global_stack; | ||
| 52 | ST_DATA Sym *local_stack; | ||
| 53 | ST_DATA Sym *define_stack; | ||
| 54 | ST_DATA Sym *global_label_stack; | ||
| 55 | ST_DATA Sym *local_label_stack; | ||
| 56 | |||
| 57 | ST_DATA SValue vstack[VSTACK_SIZE], *vtop; | ||
| 58 | |||
| 59 | ST_DATA int const_wanted; /* true if constant wanted */ | ||
| 60 | ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ | ||
| 61 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | ||
| 62 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ | ||
| 63 | ST_DATA int func_vc; | ||
| 64 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ | ||
| 65 | ST_DATA char *funcname; | ||
| 66 | |||
| 67 | ST_DATA CType char_pointer_type, func_old_type, int_type; | ||
| 68 | |||
| 69 | /* ------------------------------------------------------------------------- */ | ||
| 70 | static void gen_cast(CType *type); | ||
| 71 | static inline CType *pointed_type(CType *type); | ||
| 72 | static int is_compatible_types(CType *type1, CType *type2); | ||
| 73 | static int parse_btype(CType *type, AttributeDef *ad); | ||
| 74 | static void type_decl(CType *type, AttributeDef *ad, int *v, int td); | ||
| 75 | static void parse_expr_type(CType *type); | ||
| 76 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); | ||
| 77 | static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr); | ||
| 78 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); | ||
| 79 | static void expr_eq(void); | ||
| 80 | static void unary_type(CType *type); | ||
| 81 | static int is_compatible_parameter_types(CType *type1, CType *type2); | ||
| 82 | static void expr_type(CType *type); | ||
| 83 | |||
| 84 | ST_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 | |||
| 91 | ST_FUNC void test_lvalue(void) | ||
| 92 | { | ||
| 93 | if (!(vtop->r & VT_LVAL)) | ||
| 94 | expect("lvalue"); | ||
| 95 | } | ||
| 96 | |||
| 97 | /* ------------------------------------------------------------------------- */ | ||
| 98 | /* symbol allocator */ | ||
| 99 | static 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 | |||
| 118 | static 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 | |||
| 128 | ST_INLN void sym_free(Sym *sym) | ||
| 129 | { | ||
| 130 | sym->next = sym_free_first; | ||
| 131 | sym_free_first = sym; | ||
| 132 | } | ||
| 133 | |||
| 134 | /* push, without hashing */ | ||
| 135 | ST_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 */ | ||
| 155 | ST_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 */ | ||
| 166 | ST_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 */ | ||
| 175 | ST_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 */ | ||
| 184 | ST_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 */ | ||
| 212 | ST_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' */ | ||
| 230 | ST_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 | |||
| 258 | ST_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 | ||
| 29 | void vsetc(CType *type, int r, CValue *vc) | 266 | static 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 */ |
| 51 | void vpushi(int v) | 288 | ST_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 */ |
| 59 | void vpushll(long long v) | 296 | static 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 */ |
| 70 | static Sym *get_sym_ref(CType *type, Section *sec, | 307 | ST_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' */ |
| 95 | static Sym *external_global_sym(int v, CType *type, int r) | 331 | ST_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 | ||
| 142 | void vset(CType *type, int r, int v) | 378 | ST_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 | ||
| 150 | void vseti(int r, int v) | 386 | static 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 | ||
| 158 | void vswap(void) | 394 | ST_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 | ||
| 167 | void vpushv(SValue *v) | 403 | static 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 | ||
| 175 | void vdup(void) | 411 | static 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 */ |
| 181 | void save_reg(int r) | 417 | ST_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) */ |
| 245 | int get_reg_ex(int rc, int rc2) | 482 | ST_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 */ |
| 267 | int get_reg(int rc) | 505 | ST_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 */ |
| 305 | void save_regs(int n) | 543 | ST_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 memory | 556 | /* move register 's' to 'r', and flush previous value of r to memory |
| 319 | if needed */ | 557 | if needed */ |
| 320 | void move_reg(int r, int s) | 558 | static 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) */ |
| 334 | void gaddrof(void) | 572 | static 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_BCHECK | 580 | #ifdef CONFIG_TCC_BCHECK |
| 343 | /* generate lvalue bound code */ | 581 | /* generate lvalue bound code */ |
| 344 | void gbound(void) | 582 | static 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 are | 608 | /* store vtop a register belonging to class 'rc'. lvalues are |
| 371 | converted to values. Cannot be used if cannot be converted to | 609 | converted to values. Cannot be used if cannot be converted to |
| 372 | register value (such as structures). */ | 610 | register value (such as structures). */ |
| 373 | int gv(int rc) | 611 | ST_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 */ |
| 540 | void gv2(int rc1, int rc2) | 778 | ST_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 */ |
| 572 | int rc_fret(int t) | 810 | static int rc_fret(int t) |
| 573 | { | 811 | { |
| 574 | #ifdef TCC_TARGET_X86_64 | 812 | #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 */ |
| 583 | int reg_fret(int t) | 821 | static int reg_fret(int t) |
| 584 | { | 822 | { |
| 585 | #ifdef TCC_TARGET_X86_64 | 823 | #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 */ |
| 594 | void lexpand(void) | 832 | static 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_ARM | 846 | #ifdef TCC_TARGET_ARM |
| 609 | /* expand long long on stack */ | 847 | /* expand long long on stack */ |
| 610 | void lexpand_nr(void) | 848 | ST_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 | #endif | 872 | #endif |
| 635 | 873 | ||
| 636 | /* build a long long from two ints */ | 874 | /* build a long long from two ints */ |
| 637 | void lbuild(int t) | 875 | static 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 | */ |
| 648 | void vrotb(int n) | 886 | static 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 | */ |
| 662 | void vrott(int n) | 900 | static 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 | #endif | 925 | #endif |
| 688 | 926 | ||
| 689 | /* pop stack value */ | 927 | /* pop stack value */ |
| 690 | void vpop(void) | 928 | ST_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 another | 945 | /* convert stack entry to register and duplicate its value in another |
| 708 | register */ | 946 | register */ |
| 709 | void gv_dup(void) | 947 | static 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_64 | 992 | #ifndef TCC_TARGET_X86_64 |
| 755 | /* generate CPU independent (unsigned) long long operations */ | 993 | /* generate CPU independent (unsigned) long long operations */ |
| 756 | void gen_opl(int op) | 994 | static 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 machine | 1229 | /* handle integer constant optimizations and various machine |
| 992 | independent opt */ | 1230 | independent opt */ |
| 993 | void gen_opic(int op) | 1231 | static 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 */ |
| 1133 | void gen_opif(int op) | 1371 | static 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 */ |
| 1265 | void gen_op(int op) | 1503 | ST_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_ARM | 1650 | #ifndef TCC_TARGET_ARM |
| 1413 | /* generic itof for unsigned long long case */ | 1651 | /* generic itof for unsigned long long case */ |
| 1414 | void gen_cvt_itof1(int t) | 1652 | static 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 | #endif | 1673 | #endif |
| 1436 | 1674 | ||
| 1437 | /* generic ftoi for unsigned long long case */ | 1675 | /* generic ftoi for unsigned long long case */ |
| 1438 | void gen_cvt_ftoi1(int t) | 1676 | static 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 */ |
| 1464 | void force_charshort_cast(int t) | 1702 | static 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' */ |
| 1675 | static int type_size(CType *type, int *a) | 1913 | ST_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. */ |
| 1741 | static void mk_pointer(CType *type) | 1979 | ST_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 */ |
| 1832 | void type_to_str(char *buf, int buf_size, | 2070 | static 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 */ |
| 2003 | void vstore(void) | 2241 | ST_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 -- */ |
| 2164 | void inc(int post, int c) | 2402 | ST_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. */ |
| 2882 | static int lvalue_type(int t) | 3120 | ST_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 */ |
| 2899 | static void indir(void) | 3137 | ST_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 | ||
| 2979 | static void unary(void) | 3217 | ST_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 | ||
| 3447 | static void expr_prod(void) | 3685 | ST_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 | ||
| 3460 | static void expr_sum(void) | 3698 | ST_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 | ||
| 3748 | static void gexpr(void) | 3986 | ST_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. */ |
| 3797 | static int expr_const(void) | 4035 | ST_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 | ||
| 4851 | void put_func_debug(Sym *sym) | 5089 | static 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 | ||
| 4954 | static void gen_inline_functions(void) | 5192 | ST_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 */ |
| 4997 | static void decl(int l) | 5235 | ST_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; |
| @@ -18,11 +18,7 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #ifdef TCC_TARGET_PE | 21 | #include "tcc.h" |
| 22 | |||
| 23 | #define ST_FN static | ||
| 24 | #define ST_DATA static | ||
| 25 | #define PUB_FN | ||
| 26 | 22 | ||
| 27 | #ifndef _WIN32 | 23 | #ifndef _WIN32 |
| 28 | #define stricmp strcasecmp | 24 | #define stricmp strcasecmp |
| @@ -300,7 +296,7 @@ enum { · 271 unmodified lines | |||
| 300 | sec_last | 296 | sec_last |
| 301 | }; | 297 | }; |
| 302 | 298 | ||
| 303 | ST_DATA const DWORD pe_sec_flags[] = { | 299 | static 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 | ||
| 369 | ST_FN const char* get_alt_symbol(char *buffer, const char *symbol) | 365 | static 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 | ||
| 387 | ST_FN int pe_find_import(TCCState * s1, const char *symbol) | 383 | static 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 | ||
| 402 | ST_FN int dynarray_assoc(void **pp, int n, int key) | 398 | static 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 | #endif | 412 | #endif |
| 417 | 413 | ||
| 418 | ST_FN DWORD umax(DWORD a, DWORD b) | 414 | static DWORD umax(DWORD a, DWORD b) |
| 419 | { | 415 | { |
| 420 | return a < b ? b : a; | 416 | return a < b ? b : a; |
| 421 | } | 417 | } |
| 422 | 418 | ||
| 423 | ST_FN DWORD pe_file_align(struct pe_info *pe, DWORD n) | 419 | static 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 | ||
| 428 | ST_FN DWORD pe_virtual_align(struct pe_info *pe, DWORD n) | 424 | static 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 | ||
| 433 | ST_FN void pe_align_section(Section *s, int a) | 429 | static 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 | ||
| 440 | ST_FN void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size) | 436 | static 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 | ||
| 446 | ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum) | 442 | static 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 | ||
| 461 | ST_FN void pe_fpad(FILE *fp, DWORD new_pos) | 457 | static 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 | /*----------------------------------------------------------------------------*/ |
| 469 | ST_FN int pe_write(struct pe_info *pe) | 465 | static 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 | #endif | 741 | #endif |
| 746 | /*----------------------------------------------------------------------------*/ | 742 | /*----------------------------------------------------------------------------*/ |
| 747 | 743 | ||
| 748 | ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) | 744 | static 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 | /*----------------------------------------------------------------------------*/ |
| 780 | ST_FN void pe_build_imports(struct pe_info *pe) | 776 | static 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 | ||
| 863 | ST_FN int sym_cmp(const void *va, const void *vb) | 859 | static 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 | ||
| 870 | ST_FN void pe_build_exports(struct pe_info *pe) | 866 | static 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 | /* ------------------------------------------------------------- */ |
| 970 | ST_FN void pe_build_reloc (struct pe_info *pe) | 966 | static 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 | /* ------------------------------------------------------------- */ |
| 1026 | ST_FN int pe_section_class(Section *s) | 1022 | static 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 | ||
| 1058 | ST_FN int pe_assign_addresses (struct pe_info *pe) | 1054 | static 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 | /* ------------------------------------------------------------- */ |
| 1156 | ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s) | 1152 | static 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 | |||
| 1176 | static int pe_isafunc(int sym_index) | 1173 | static 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 | /*----------------------------------------------------------------------------*/ |
| 1191 | ST_FN int pe_check_symbols(struct pe_info *pe) | 1188 | static 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_SECTIONS | 1281 | #ifdef PE_PRINT_SECTIONS |
| 1285 | ST_FN void pe_print_section(FILE * f, Section * s) | 1282 | static 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 | ||
| 1407 | ST_FN void pe_print_sections(TCCState *s1, const char *fname) | 1404 | static 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 | #endif | 1417 | #endif |
| 1421 | 1418 | ||
| 1422 | /* ------------------------------------------------------------- */ | 1419 | /* ------------------------------------------------------------- */ |
| 1423 | /* helper function for load/store to insert one more indirection */ | ||
| 1424 | 1420 | ||
| 1425 | int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)) | 1421 | static 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 | |||
| 1450 | ST_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 | ||
| 1461 | ST_FN int pe_load_res(TCCState *s1, FILE *fp) | 1432 | static 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 | /* ------------------------------------------------------------- */ |
| 1501 | ST_FN char *trimfront(char *p) | 1472 | static 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 | ||
| 1508 | ST_FN char *trimback(char *a, char *e) | 1479 | static 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 | ||
| 1516 | ST_FN char *get_line(char *line, int size, FILE *fp) | 1487 | static 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 | /* ------------------------------------------------------------- */ |
| 1525 | ST_FN int pe_load_def(TCCState *s1, FILE *fp) | 1496 | static 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_ONLY | 1542 | #define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY |
| 1572 | #include "win32/tools/tiny_impdef.c" | 1543 | #include "win32/tools/tiny_impdef.c" |
| 1573 | 1544 | ||
| 1574 | ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp) | 1545 | static 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 | /* ------------------------------------------------------------- */ |
| 1597 | PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd) | 1568 | ST_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 | ||
| 1614 | int pe_add_dll(struct TCCState *s, const char *libname) | 1585 | ST_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", NULL | 1588 | "%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 | |||
| 1603 | ST_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_64 | 1627 | #ifdef TCC_TARGET_X86_64 |
| 1631 | #define PE_STDSYM(n,s) n | 1628 | #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 s | 1630 | #define PE_STDSYM(n,s) "_" n s |
| 1634 | #endif | 1631 | #endif |
| 1635 | 1632 | ||
| 1636 | ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) | 1633 | static 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 | ||
| 1693 | PUB_FN int pe_output_file(TCCState * s1, const char *filename) | 1690 | ST_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 | /* ------------------------------------------------------------- */ | ||
| @@ -18,6 +18,49 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * 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 | |||
| 26 | ST_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 | |||
| 33 | ST_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 | |||
| 42 | ST_DATA struct BufferedFile *file; | ||
| 43 | ST_DATA int ch, tok; | ||
| 44 | ST_DATA CValue tokc; | ||
| 45 | ST_DATA int *macro_ptr; | ||
| 46 | ST_DATA CString tokcstr; /* current parsed string, if any */ | ||
| 47 | |||
| 48 | /* display benchmark infos */ | ||
| 49 | ST_DATA int total_lines; | ||
| 50 | ST_DATA int total_bytes; | ||
| 51 | ST_DATA int tok_ident; | ||
| 52 | ST_DATA TokenSym **table_ident; | ||
| 53 | |||
| 54 | /* ------------------------------------------------------------------------- */ | ||
| 55 | |||
| 56 | static int *macro_ptr_allocated; | ||
| 57 | static int *unget_saved_macro_ptr; | ||
| 58 | static int unget_saved_buffer[TOK_MAX_SIZE + 1]; | ||
| 59 | static int unget_buffer_enabled; | ||
| 60 | static TokenSym *hash_ident[TOK_HASH_SIZE]; | ||
| 61 | static char token_buf[STRING_MAX_SIZE + 1]; | ||
| 62 | /* true if isid(c) || isnum(c) */ | ||
| 63 | static unsigned char isidnum_table[256-CH_EOF]; | ||
| 21 | 64 | ||
| 22 | static const char tcc_keywords[] = | 65 | static 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) */ | ||
| 34 | static unsigned char isidnum_table[256-CH_EOF]; | ||
| 35 | |||
| 36 | |||
| 37 | struct macro_level { | 76 | struct macro_level { |
| 38 | struct macro_level *prev; | 77 | struct macro_level *prev; |
| 39 | int *p; | 78 | int *p; |
| 40 | }; | 79 | }; |
| 41 | 80 | ||
| 42 | static void next_nomacro(void); | 81 | ST_FUNC void next_nomacro(void); |
| 43 | static void next_nomacro_spc(void); | 82 | static void next_nomacro_spc(void); |
| 44 | static void macro_subst(TokenString *tok_str, Sym **nested_list, | 83 | static 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 | |||
| 90 | ST_FUNC void skip(int c) | ||
| 91 | { | ||
| 92 | if (tok != c) | ||
| 93 | error("'%c' expected", c); | ||
| 94 | next(); | ||
| 95 | } | ||
| 46 | 96 | ||
| 97 | /* ------------------------------------------------------------------------- */ | ||
| 98 | /* CString handling */ | ||
| 99 | static 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 */ | ||
| 118 | ST_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 | |||
| 128 | ST_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 */ | ||
| 141 | ST_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 | |||
| 151 | ST_FUNC void cstr_new(CString *cstr) | ||
| 152 | { | ||
| 153 | memset(cstr, 0, sizeof(CString)); | ||
| 154 | } | ||
| 155 | |||
| 156 | /* free string and reset it to NULL */ | ||
| 157 | ST_FUNC void cstr_free(CString *cstr) | ||
| 158 | { | ||
| 159 | tcc_free(cstr->data_allocated); | ||
| 160 | cstr_new(cstr); | ||
| 161 | } | ||
| 162 | |||
| 163 | /* XXX: unicode ? */ | ||
| 164 | ST_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 */ |
| 49 | static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) | 186 | static 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 */ |
| 85 | static TokenSym *tok_alloc(const char *str, int len) | 222 | ST_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 */ |
| 110 | char *get_tok_str(int v, CValue *cv) | 247 | ST_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 necessary | 381 | /* return the current character, handling end of block if necessary |
| 245 | (but not stray) */ | 382 | (but not stray) */ |
| 246 | static int handle_eob(void) | 383 | ST_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 */ |
| 252 | static inline void inp(void) | 389 | ST_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 cannot | 471 | /* input with '\[\r]\n' handling. Note that this function cannot |
| 335 | handle other characters after '\', so you cannot call it inside | 472 | handle other characters after '\', so you cannot call it inside |
| 336 | strings or comments */ | 473 | strings or comments */ |
| 337 | static void minp(void) | 474 | ST_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 */ |
| 383 | static uint8_t *parse_comment(uint8_t *p) | 520 | ST_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 of | 675 | /* skip block of text until #else, #elif or #endif. skip also pairs of |
| 539 | #if/#endif */ | 676 | #if/#endif */ |
| 540 | void preprocess_skip(void) | 677 | static 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' */ |
| 632 | void save_parse_state(ParseState *s) | 769 | ST_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' */ |
| 641 | void restore_parse_state(ParseState *s) | 778 | ST_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 | ||
| 680 | static inline void tok_str_new(TokenString *s) | 817 | ST_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 | ||
| 688 | static void tok_str_free(int *str) | 825 | ST_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 | ||
| 710 | static void tok_str_add(TokenString *s, int t) | 847 | ST_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' */ |
| 793 | static void tok_str_add_tok(TokenString *s) | 930 | ST_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 */ |
| 864 | static inline void define_push(int v, int macro_type, int *str, Sym *first_arg) | 1001 | ST_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 */ |
| 875 | static void define_undef(Sym *s) | 1012 | ST_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 | ||
| 884 | static inline Sym *define_find(int v) | 1021 | ST_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' */ |
| 893 | static void free_defines(Sym *b) | 1030 | ST_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 */ |
| 914 | static Sym *label_find(int v) | 1051 | ST_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 | ||
| 922 | static Sym *label_push(Sym **ptop, int v, int flags) | 1059 | ST_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 are | 1076 | /* 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. */ |
| 941 | static void label_pop(Sym **ptop, Sym *slast) | 1078 | ST_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 | #endif | 1154 | #endif |
| 1018 | 1155 | ||
| 1019 | /* parse after #define */ | 1156 | /* parse after #define */ |
| 1020 | static void parse_define(void) | 1157 | ST_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 */ |
| 1196 | static void preprocess(int is_bof) | 1333 | ST_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 2 | 1735 | #define BN_SIZE 2 |
| 1599 | 1736 | ||
| 1600 | /* bn = (bn << shift) | or_val */ | 1737 | /* bn = (bn << shift) | or_val */ |
| 1601 | void bn_lshift(unsigned int *bn, int shift, int or_val) | 1738 | static 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 | ||
| 1612 | void bn_zero(unsigned int *bn) | 1749 | static 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 the | 1757 | /* parse number in null terminated string 'p' and return it in the |
| 1621 | current token */ | 1758 | current token */ |
| 1622 | void parse_number(const char *p) | 1759 | static 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 | ||
| 2356 | static void next_nomacro(void) | 2493 | ST_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 */ |
| 2737 | static void next(void) | 2874 | ST_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'. Only | 2928 | /* push back current token and set current token to 'last_tok'. Only |
| 2792 | identifier case handled for labels. */ | 2929 | identifier case handled for labels. */ |
| 2793 | static inline void unget_tok(int last_tok) | 2930 | ST_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' option | 2947 | /* better than nothing, but needs extension to handle '-E' option |
| 2811 | correctly too */ | 2948 | correctly too */ |
| 2812 | static void preprocess_init(TCCState *s1) | 2949 | ST_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 initialize | 2952 | /* 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 | ||
| 2826 | void preprocess_new() | 2963 | ST_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 */ |
| 2855 | static int tcc_preprocess(TCCState *s1) | 2992 | ST_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 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * TCC - Tiny C Compiler | 2 | * TCC - Tiny C Compiler - Support for -run switch |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2001-2004 Fabrice Bellard | 4 | * 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 USA | 18 | * 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 _WIN32 | 23 | #ifdef _WIN32 |
| 24 | #define ucontext_t CONTEXT | 24 | #define ucontext_t CONTEXT |
| @@ -26,7 +26,7 @@ · 1 unmodified line | |||
| 26 | 26 | ||
| 27 | static void set_pages_executable(void *ptr, unsigned long length); | 27 | static void set_pages_executable(void *ptr, unsigned long length); |
| 28 | static void set_exception_handler(void); | 28 | static void set_exception_handler(void); |
| 29 | static int rt_get_caller_pc(unsigned long *paddr, ucontext_t *uc, int level); | 29 | static int rt_get_caller_pc(uplong *paddr, ucontext_t *uc, int level); |
| 30 | static void rt_error(ucontext_t *uc, const char *fmt, ...); | 30 | static void rt_error(ucontext_t *uc, const char *fmt, ...); |
| 31 | static int tcc_relocate_ex(TCCState *s1, void *ptr); | 31 | static 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 | #else | 174 | #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 | #endif | 180 | #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 reading | 186 | /* print the position in the source file of PC value 'pc' by reading |
| 187 | the stabs debug information */ | 187 | the stabs debug information */ |
| 188 | static unsigned long rt_printline(unsigned long wanted_pc) | 188 | static 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 | |||
| 311 | static void rt_error(ucontext_t *uc, const char *fmt, ...) | 311 | static 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 | else | 327 | 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 */ |
| 509 | static int rt_get_caller_pc(unsigned long *paddr, | 514 | static 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 | ||
| 595 | void *resolve_sym(TCCState *s1, const char *sym) | 596 | void *resolve_sym(TCCState *s1, const char *sym) |
| 596 | { | 597 | { |
| @@ -20,10 +20,11 @@ · 19 unmodified lines | |||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * 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 5 | 26 | #define NB_REGS 5 |
| 27 | #define NB_ASM_REGS 8 | ||
| 27 | 28 | ||
| 28 | /* a register can belong to several classes. The classes must be | 29 | /* a register can belong to several classes. The classes must be |
| 29 | sorted from more general to more precise (see gv2() code which does | 30 | 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 | ||
| 63 | const 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 8 | 79 | #define MAX_ALIGN 8 |
| 87 | 80 | ||
| 81 | ST_FUNC void gen_opl(int op); | ||
| 82 | ST_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 0x1000 | 96 | #define ELF_PAGE_SIZE 0x1000 |
| 101 | 97 | ||
| 102 | /******************************************************/ | 98 | /******************************************************/ |
| 99 | #else /* ! TARGET_DEFS_ONLY */ | ||
| 100 | /******************************************************/ | ||
| 101 | #include "tcc.h" | ||
| 102 | #include <assert.h> | ||
| 103 | |||
| 104 | ST_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 | ||
| 104 | static unsigned long func_sub_sp_offset; | 112 | static unsigned long func_sub_sp_offset; |
| 105 | static int func_ret_sub; | 113 | static 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 */ |
| 187 | static int oad(int c, int s) | 195 | ST_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 | ||
| 201 | static void gen_addr32(int r, Sym *sym, int c) | 209 | ST_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 */ |
| 209 | static void gen_addr64(int r, Sym *sym, int64_t c) | 217 | ST_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 */ |
| 217 | static void gen_addrpc32(int r, Sym *sym, int c) | 225 | ST_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 | /******************************************************/ | ||