added archive support - better ELF output - fixed symbol relocation - added COMMON...
[tinycc.git] / tcc.c
blob7dde955fb5666e12e80a920ea5f0e0c8d1640368
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <malloc.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #ifndef WIN32
32 #include <sys/ucontext.h>
33 #include <sys/mman.h>
34 #endif
35 #include "elf.h"
36 #include "stab.h"
37 #ifndef CONFIG_TCC_STATIC
38 #include <dlfcn.h>
39 #endif
41 #include "libtcc.h"
43 //#define DEBUG
44 /* preprocessor debug */
45 //#define PP_DEBUG
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
54 #endif
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
58 #endif
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
62 #endif
64 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
65 executables or dlls */
66 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
68 /* amount of virtual memory associated to a section (currently, we do
69 not realloc them) */
70 #define SECTION_VSIZE (1024 * 1024)
72 #define INCLUDE_STACK_SIZE 32
73 #define IFDEF_STACK_SIZE 64
74 #define VSTACK_SIZE 64
75 #define STRING_MAX_SIZE 1024
76 #define INCLUDE_PATHS_MAX 32
78 #define TOK_HASH_SIZE 2048 /* must be a power of two */
79 #define TOK_ALLOC_INCR 512 /* must be a power of two */
80 #define SYM_HASH_SIZE 1031
81 #define ELF_SYM_HASH_SIZE 2048
82 #define ELF_DYNSYM_HASH_SIZE 32
84 /* token symbol management */
85 typedef struct TokenSym {
86 struct TokenSym *hash_next;
87 int tok; /* token number */
88 int len;
89 char str[1];
90 } TokenSym;
92 /* constant value */
93 typedef union CValue {
94 long double ld;
95 double d;
96 float f;
97 int i;
98 unsigned int ui;
99 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
100 long long ll;
101 unsigned long long ull;
102 struct TokenSym *ts;
103 struct Sym *sym;
104 int tab[1];
105 } CValue;
107 /* value on stack */
108 typedef struct SValue {
109 int t; /* type */
110 unsigned short r; /* register + flags */
111 unsigned short r2; /* second register, used for 'long long'
112 type. If not used, set to VT_CONST */
113 CValue c; /* constant, if VT_CONST */
114 } SValue;
116 /* symbol management */
117 typedef struct Sym {
118 int v; /* symbol token */
119 int t; /* associated type */
120 int r; /* associated register */
121 int c; /* associated number */
122 struct Sym *next; /* next related symbol */
123 struct Sym *prev; /* prev symbol in stack */
124 struct Sym *hash_next; /* next symbol in hash table */
125 } Sym;
127 typedef struct SymStack {
128 struct Sym *top;
129 struct Sym *hash[SYM_HASH_SIZE];
130 } SymStack;
132 /* section definition */
133 /* XXX: use directly ELF structure for parameters ? */
134 /* special flag to indicate that the section should not be linked to
135 the other ones */
136 #define SHF_PRIVATE 0x80000000
138 typedef struct Section {
139 unsigned char *data; /* section data */
140 unsigned char *data_ptr; /* current data pointer */
141 int sh_name; /* elf section name (only used during output) */
142 int sh_num; /* elf section number */
143 int sh_type; /* elf section type */
144 int sh_flags; /* elf section flags */
145 int sh_info; /* elf section info */
146 int sh_addralign; /* elf section alignment */
147 int sh_entsize; /* elf entry size */
148 unsigned long sh_size; /* section size (only used during output) */
149 unsigned long sh_addr; /* address at which the section is relocated */
150 unsigned long sh_offset; /* address at which the section is relocated */
151 struct Section *link; /* link to another section */
152 struct Section *reloc; /* corresponding section for relocation, if any */
153 struct Section *hash; /* hash table for symbols */
154 struct Section *next;
155 char name[64]; /* section name */
156 } Section;
158 /* GNUC attribute definition */
159 typedef struct AttributeDef {
160 int aligned;
161 Section *section;
162 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
163 } AttributeDef;
165 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
166 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
167 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
169 /* stored in 'Sym.c' field */
170 #define FUNC_NEW 1 /* ansi function prototype */
171 #define FUNC_OLD 2 /* old function prototype */
172 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
174 /* stored in 'Sym.r' field */
175 #define FUNC_CDECL 0 /* standard c call */
176 #define FUNC_STDCALL 1 /* pascal c call */
178 /* field 'Sym.t' for macros */
179 #define MACRO_OBJ 0 /* object like macro */
180 #define MACRO_FUNC 1 /* function like macro */
182 /* field 'Sym.t' for labels */
183 #define LABEL_FORWARD 1 /* label is forward defined */
185 /* type_decl() types */
186 #define TYPE_ABSTRACT 1 /* type without variable */
187 #define TYPE_DIRECT 2 /* type with variable */
189 #define IO_BUF_SIZE 8192
191 typedef struct BufferedFile {
192 unsigned char *buf_ptr;
193 unsigned char *buf_end;
194 int fd;
195 int line_num; /* current line number - here to simply code */
196 char filename[1024]; /* current filename - here to simply code */
197 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
198 } BufferedFile;
200 #define CH_EOB 0 /* end of buffer or '\0' char in file */
201 #define CH_EOF (-1) /* end of file */
203 /* parsing state (used to save parser state to reparse part of the
204 source several times) */
205 typedef struct ParseState {
206 int *macro_ptr;
207 int line_num;
208 int tok;
209 CValue tokc;
210 } ParseState;
212 /* used to record tokens */
213 typedef struct TokenString {
214 int *str;
215 int len;
216 int last_line_num;
217 } TokenString;
219 /* parser */
220 struct BufferedFile *file;
221 int ch, ch1, tok, tok1;
222 CValue tokc, tok1c;
224 /* sections */
225 /* XXX: suppress first_section */
226 Section *first_section, **sections;
227 int nb_sections; /* number of sections, including first dummy section */
228 int nb_allocated_sections;
229 Section *text_section, *data_section, *bss_section; /* predefined sections */
230 Section *cur_text_section; /* current section where function code is
231 generated */
232 /* bound check related sections */
233 Section *bounds_section; /* contains global data bound description */
234 Section *lbounds_section; /* contains local data bound description */
235 /* symbol sections */
236 Section *symtab_section, *strtab_section;
238 /* debug sections */
239 Section *stab_section, *stabstr_section;
241 /* loc : local variable index
242 ind : output code index
243 rsym: return symbol
244 anon_sym: anonymous symbol index
246 int rsym, anon_sym,
247 prog, ind, loc, const_wanted;
248 int global_expr; /* true if compound literals must be allocated
249 globally (used during initializers parsing */
250 int func_vt, func_vc; /* current function return type (used by
251 return instruction) */
252 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
253 int tok_ident;
254 TokenSym **table_ident;
255 TokenSym *hash_ident[TOK_HASH_SIZE];
256 char token_buf[STRING_MAX_SIZE + 1];
257 char *funcname;
258 SymStack define_stack, global_stack, local_stack, label_stack;
260 SValue vstack[VSTACK_SIZE], *vtop;
261 int *macro_ptr, *macro_ptr_allocated;
262 BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr;
263 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
264 char *include_paths[INCLUDE_PATHS_MAX];
265 int nb_include_paths;
266 int char_pointer_type;
268 /* compile with debug symbol (and use them if error during execution) */
269 int do_debug = 0;
271 /* compile with built-in memory and bounds checker */
272 int do_bounds_check = 0;
274 /* display benchmark infos */
275 int do_bench = 0;
276 int total_lines;
277 int total_bytes;
279 /* use GNU C extensions */
280 int gnu_ext = 1;
282 /* use Tiny C extensions */
283 int tcc_ext = 1;
285 /* if true, static linking is performed */
286 int static_link = 0;
288 struct TCCState {
289 int dummy;
292 /* The current value can be: */
293 #define VT_VALMASK 0x00ff
294 #define VT_CONST 0x00f0 /* constant in vc
295 (must be first non register value) */
296 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
297 #define VT_LOCAL 0x00f2 /* offset on stack */
298 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
299 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
300 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
301 #define VT_LVAL 0x0100 /* var is an lvalue */
302 #define VT_SYM 0x0200 /* a symbol value is added */
303 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
304 char/short stored in integer registers) */
305 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
306 dereferencing value */
307 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
308 bounding function call point is in vc */
309 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
310 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
311 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
312 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
314 /* types */
315 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
317 #define VT_INT 0 /* integer type */
318 #define VT_BYTE 1 /* signed byte type */
319 #define VT_SHORT 2 /* short type */
320 #define VT_VOID 3 /* void type */
321 #define VT_PTR 4 /* pointer */
322 #define VT_ENUM 5 /* enum definition */
323 #define VT_FUNC 6 /* function type */
324 #define VT_STRUCT 7 /* struct/union definition */
325 #define VT_FLOAT 8 /* IEEE float */
326 #define VT_DOUBLE 9 /* IEEE double */
327 #define VT_LDOUBLE 10 /* IEEE long double */
328 #define VT_BOOL 11 /* ISOC99 boolean type */
329 #define VT_LLONG 12 /* 64 bit integer */
330 #define VT_LONG 13 /* long integer (NEVER USED as type, only
331 during parsing) */
332 #define VT_BTYPE 0x000f /* mask for basic type */
333 #define VT_UNSIGNED 0x0010 /* unsigned type */
334 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
335 #define VT_BITFIELD 0x0040 /* bitfield modifier */
337 /* storage */
338 #define VT_EXTERN 0x00000080 /* extern definition */
339 #define VT_STATIC 0x00000100 /* static variable */
340 #define VT_TYPEDEF 0x00000200 /* typedef definition */
342 /* type mask (except storage) */
343 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
345 /* token values */
347 /* warning: the following compare tokens depend on i386 asm code */
348 #define TOK_ULT 0x92
349 #define TOK_UGE 0x93
350 #define TOK_EQ 0x94
351 #define TOK_NE 0x95
352 #define TOK_ULE 0x96
353 #define TOK_UGT 0x97
354 #define TOK_LT 0x9c
355 #define TOK_GE 0x9d
356 #define TOK_LE 0x9e
357 #define TOK_GT 0x9f
359 #define TOK_LAND 0xa0
360 #define TOK_LOR 0xa1
362 #define TOK_DEC 0xa2
363 #define TOK_MID 0xa3 /* inc/dec, to void constant */
364 #define TOK_INC 0xa4
365 #define TOK_UDIV 0xb0 /* unsigned division */
366 #define TOK_UMOD 0xb1 /* unsigned modulo */
367 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
368 #define TOK_CINT 0xb3 /* number in tokc */
369 #define TOK_CCHAR 0xb4 /* char constant in tokc */
370 #define TOK_STR 0xb5 /* pointer to string in tokc */
371 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
372 #define TOK_LCHAR 0xb7
373 #define TOK_LSTR 0xb8
374 #define TOK_CFLOAT 0xb9 /* float constant */
375 #define TOK_LINENUM 0xba /* line number info */
376 #define TOK_CDOUBLE 0xc0 /* double constant */
377 #define TOK_CLDOUBLE 0xc1 /* long double constant */
378 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
379 #define TOK_ADDC1 0xc3 /* add with carry generation */
380 #define TOK_ADDC2 0xc4 /* add with carry use */
381 #define TOK_SUBC1 0xc5 /* add with carry generation */
382 #define TOK_SUBC2 0xc6 /* add with carry use */
383 #define TOK_CUINT 0xc8 /* unsigned int constant */
384 #define TOK_CLLONG 0xc9 /* long long constant */
385 #define TOK_CULLONG 0xca /* unsigned long long constant */
386 #define TOK_ARROW 0xcb
387 #define TOK_DOTS 0xcc /* three dots */
388 #define TOK_SHR 0xcd /* unsigned shift right */
390 #define TOK_SHL 0x01 /* shift left */
391 #define TOK_SAR 0x02 /* signed shift right */
393 /* assignement operators : normal operator or 0x80 */
394 #define TOK_A_MOD 0xa5
395 #define TOK_A_AND 0xa6
396 #define TOK_A_MUL 0xaa
397 #define TOK_A_ADD 0xab
398 #define TOK_A_SUB 0xad
399 #define TOK_A_DIV 0xaf
400 #define TOK_A_XOR 0xde
401 #define TOK_A_OR 0xfc
402 #define TOK_A_SHL 0x81
403 #define TOK_A_SAR 0x82
405 #define TOK_EOF (-1) /* end of file */
407 /* all identificators and strings have token above that */
408 #define TOK_IDENT 256
410 enum {
411 TOK_INT = TOK_IDENT,
412 TOK_VOID,
413 TOK_CHAR,
414 TOK_IF,
415 TOK_ELSE,
416 TOK_WHILE,
417 TOK_BREAK,
418 TOK_RETURN,
419 TOK_FOR,
420 TOK_EXTERN,
421 TOK_STATIC,
422 TOK_UNSIGNED,
423 TOK_GOTO,
424 TOK_DO,
425 TOK_CONTINUE,
426 TOK_SWITCH,
427 TOK_CASE,
429 /* ignored types Must have contiguous values */
430 TOK_CONST,
431 TOK_VOLATILE,
432 TOK_LONG,
433 TOK_REGISTER,
434 TOK_SIGNED,
435 TOK___SIGNED__, /* gcc keyword */
436 TOK_AUTO,
437 TOK_INLINE,
438 TOK___INLINE__, /* gcc keyword */
439 TOK_RESTRICT,
441 /* unsupported type */
442 TOK_FLOAT,
443 TOK_DOUBLE,
444 TOK_BOOL,
446 TOK_SHORT,
447 TOK_STRUCT,
448 TOK_UNION,
449 TOK_TYPEDEF,
450 TOK_DEFAULT,
451 TOK_ENUM,
452 TOK_SIZEOF,
453 TOK___ATTRIBUTE__,
455 /* preprocessor only */
456 TOK_UIDENT, /* first "user" ident (not keyword) */
457 TOK_DEFINE = TOK_UIDENT,
458 TOK_INCLUDE,
459 TOK_IFDEF,
460 TOK_IFNDEF,
461 TOK_ELIF,
462 TOK_ENDIF,
463 TOK_DEFINED,
464 TOK_UNDEF,
465 TOK_ERROR,
466 TOK_LINE,
467 TOK___LINE__,
468 TOK___FILE__,
469 TOK___DATE__,
470 TOK___TIME__,
471 TOK___VA_ARGS__,
473 /* special identifiers */
474 TOK___FUNC__,
475 TOK_MAIN,
476 /* attribute identifiers */
477 TOK_SECTION,
478 TOK___SECTION__,
479 TOK_ALIGNED,
480 TOK___ALIGNED__,
481 TOK_UNUSED,
482 TOK___UNUSED__,
483 TOK_CDECL,
484 TOK___CDECL,
485 TOK___CDECL__,
486 TOK_STDCALL,
487 TOK___STDCALL,
488 TOK___STDCALL__,
489 TOK_NORETURN,
490 TOK___NORETURN__,
493 char *tcc_keywords =
494 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
495 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
496 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
497 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
498 "sizeof\0__attribute__\0"
499 /* the following are not keywords. They are included to ease parsing */
500 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
501 "defined\0undef\0error\0line\0"
502 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
503 "__func__\0main\0"
504 /* attributes */
505 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
506 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
507 "noreturn\0__noreturn__\0"
510 #ifdef WIN32
511 #define snprintf _snprintf
512 #endif
514 #if defined(WIN32) || defined(TCC_UCLIBC)
515 /* currently incorrect */
516 long double strtold(const char *nptr, char **endptr)
518 return (long double)strtod(nptr, endptr);
520 float strtof(const char *nptr, char **endptr)
522 return (float)strtod(nptr, endptr);
524 #else
525 /* XXX: need to define this to use them in non ISOC99 context */
526 extern float strtof (const char *__nptr, char **__endptr);
527 extern long double strtold (const char *__nptr, char **__endptr);
528 #endif
530 char *pstrcpy(char *buf, int buf_size, const char *s);
531 char *pstrcat(char *buf, int buf_size, const char *s);
533 void sum(int l);
534 void next(void);
535 void next_nomacro(void);
536 int expr_const(void);
537 void expr_eq(void);
538 void gexpr(void);
539 void decl(int l);
540 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only);
541 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
542 int v, int scope);
543 int gv(int rc);
544 void gv2(int rc1, int rc2);
545 void move_reg(int r, int s);
546 void save_regs(int n);
547 void save_reg(int r);
548 void vpop(void);
549 void vswap(void);
550 void vdup(void);
551 int get_reg(int rc);
553 void macro_subst(TokenString *tok_str,
554 Sym **nested_list, int *macro_str);
555 int save_reg_forced(int r);
556 void gen_op(int op);
557 void force_charshort_cast(int t);
558 void gen_cast(int t);
559 void vstore(void);
560 Sym *sym_find(int v);
561 Sym *sym_push(int v, int t, int r, int c);
563 /* type handling */
564 int type_size(int t, int *a);
565 int pointed_type(int t);
566 int pointed_size(int t);
567 int is_compatible_types(int t1, int t2);
568 int parse_btype(int *type_ptr, AttributeDef *ad);
569 int type_decl(AttributeDef *ad, int *v, int t, int td);
571 void error(const char *fmt, ...);
572 void rt_error(unsigned long pc, const char *fmt, ...);
573 void vpushi(int v);
574 void vset(int t, int r, int v);
575 void type_to_str(char *buf, int buf_size,
576 int t, const char *varstr);
577 char *get_tok_str(int v, CValue *cv);
579 /* section generation */
580 void put_extern_sym(Sym *sym, Section *section, unsigned long value);
581 void greloc(Section *s, Sym *sym, unsigned long addr, int type);
582 static int put_elf_str(Section *s, const char *sym);
583 static int put_elf_sym(Section *s,
584 unsigned long value, unsigned long size,
585 int info, int other, int shndx, const char *name);
586 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
587 int type, int symbol);
588 static void put_stabs(const char *str, int type, int other, int desc, int value);
589 static void put_stabn(int type, int other, int desc, int value);
590 static void put_stabd(int type, int other, int desc);
592 /* true if float/double/long double type */
593 static inline int is_float(int t)
595 int bt;
596 bt = t & VT_BTYPE;
597 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
600 #ifdef CONFIG_TCC_BCHECK
601 #include "bcheck.c"
602 #endif
604 #ifdef TCC_TARGET_I386
605 #include "i386-gen.c"
606 #endif
607 #ifdef TCC_TARGET_IL
608 #include "il-gen.c"
609 #endif
611 #ifdef CONFIG_TCC_STATIC
613 #define RTLD_LAZY 0x001
614 #define RTLD_NOW 0x002
615 #define RTLD_GLOBAL 0x100
617 /* dummy function for profiling */
618 void *dlopen(const char *filename, int flag)
620 return NULL;
623 const char *dlerror(void)
625 return "error";
628 typedef struct TCCSyms {
629 char *str;
630 void *ptr;
631 } TCCSyms;
633 #define TCCSYM(a) { #a, &a, },
635 /* add the symbol you want here if no dynamic linking is done */
636 static TCCSyms tcc_syms[] = {
637 TCCSYM(printf)
638 TCCSYM(fprintf)
639 TCCSYM(fopen)
640 TCCSYM(fclose)
641 { NULL, NULL },
644 void *dlsym(void *handle, const char *symbol)
646 TCCSyms *p;
647 p = tcc_syms;
648 while (p->str != NULL) {
649 if (!strcmp(p->str, symbol))
650 return p->ptr;
651 p++;
653 return NULL;
656 #endif
658 /********************************************************/
659 /* runtime library is there */
660 /* XXX: we suppose that the host compiler handles 'long long'. It
661 would not be difficult to suppress this assumption */
663 long long __divll(long long a, long long b)
665 return a / b;
668 long long __modll(long long a, long long b)
670 return a % b;
673 unsigned long long __divull(unsigned long long a, unsigned long long b)
675 return a / b;
678 unsigned long long __modull(unsigned long long a, unsigned long long b)
680 return a % b;
683 long long __sardi3(long long a, int b)
685 return a >> b;
688 unsigned long long __shrdi3(unsigned long long a, int b)
690 return a >> b;
693 long long __shldi3(long long a, int b)
695 return a << b;
698 float __ulltof(unsigned long long a)
700 return (float)a;
703 double __ulltod(unsigned long long a)
705 return (double)a;
708 long double __ulltold(unsigned long long a)
710 return (long double)a;
713 unsigned long long __ftoull(float a)
715 return (unsigned long long)a;
718 unsigned long long __dtoull(double a)
720 return (unsigned long long)a;
723 unsigned long long __ldtoull(long double a)
725 return (unsigned long long)a;
729 /********************************************************/
731 /* we use our own 'finite' function to avoid potential problems with
732 non standard math libs */
733 /* XXX: endianness dependant */
734 int ieee_finite(double d)
736 int *p = (int *)&d;
737 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
740 /* copy a string and truncate it. */
741 char *pstrcpy(char *buf, int buf_size, const char *s)
743 char *q, *q_end;
744 int c;
746 if (buf_size > 0) {
747 q = buf;
748 q_end = buf + buf_size - 1;
749 while (q < q_end) {
750 c = *s++;
751 if (c == '\0')
752 break;
753 *q++ = c;
755 *q = '\0';
757 return buf;
760 /* strcat and truncate. */
761 char *pstrcat(char *buf, int buf_size, const char *s)
763 int len;
764 len = strlen(buf);
765 if (len < buf_size)
766 pstrcpy(buf + len, buf_size - len, s);
767 return buf;
770 Section *new_section(const char *name, int sh_type, int sh_flags)
772 Section *sec, **psec;
773 void *data;
775 sec = malloc(sizeof(Section));
776 if (!sec)
777 error("memory full");
778 memset(sec, 0, sizeof(Section));
779 pstrcpy(sec->name, sizeof(sec->name), name);
780 sec->sh_type = sh_type;
781 sec->sh_flags = sh_flags;
782 switch(sh_type) {
783 case SHT_HASH:
784 case SHT_REL:
785 case SHT_DYNSYM:
786 case SHT_SYMTAB:
787 case SHT_DYNAMIC:
788 sec->sh_addralign = 4;
789 break;
790 case SHT_STRTAB:
791 sec->sh_addralign = 1;
792 break;
793 default:
794 sec->sh_addralign = 32; /* default conservative alignment */
795 break;
797 #ifdef WIN32
798 /* XXX: currently, a single malloc */
799 data = malloc(SECTION_VSIZE);
800 if (data == NULL)
801 error("could not alloc section '%s'", name);
802 #else
803 data = mmap(NULL, SECTION_VSIZE,
804 PROT_EXEC | PROT_READ | PROT_WRITE,
805 MAP_PRIVATE | MAP_ANONYMOUS,
806 -1, 0);
807 if (data == (void *)(-1))
808 error("could not mmap section '%s'", name);
809 #endif
810 sec->data = data;
811 sec->data_ptr = data;
813 if (!(sh_flags & SHF_PRIVATE)) {
814 /* only add section if not private */
816 psec = &first_section;
817 while (*psec != NULL)
818 psec = &(*psec)->next;
819 sec->next = NULL;
820 *psec = sec;
822 if ((nb_sections + 1) > nb_allocated_sections) {
823 if (nb_allocated_sections == 0)
824 nb_allocated_sections = 1;
825 nb_allocated_sections *= 2;
826 sections = realloc(sections,
827 nb_allocated_sections * sizeof(Section *));
828 if (!sections)
829 error("memory full");
831 sections[nb_sections] = sec;
832 sec->sh_num = nb_sections;
833 nb_sections++;
835 return sec;
838 /* return a reference to a section, and create it if it does not
839 exists */
840 Section *find_section(const char *name)
842 Section *sec;
844 for(sec = first_section; sec != NULL; sec = sec->next) {
845 if (!strcmp(name, sec->name))
846 return sec;
848 /* sections are created as PROGBITS */
849 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
852 /* add a new relocation entry to symbol 'sym' in section 's' */
853 void greloc(Section *s, Sym *sym, unsigned long offset, int type)
855 if (!sym->c)
856 put_extern_sym(sym, NULL, 0);
857 /* now we can add ELF relocation info */
858 put_elf_reloc(symtab_section, s, offset, type, sym->c);
861 static inline int isid(int c)
863 return (c >= 'a' && c <= 'z') ||
864 (c >= 'A' && c <= 'Z') ||
865 c == '_';
868 static inline int isnum(int c)
870 return c >= '0' && c <= '9';
873 static inline int toup(int c)
875 if (ch >= 'a' && ch <= 'z')
876 return ch - 'a' + 'A';
877 else
878 return ch;
881 void printline(void)
883 BufferedFile **f;
884 if (file) {
885 for(f = include_stack; f < include_stack_ptr; f++)
886 fprintf(stderr, "In file included from %s:%d:\n",
887 (*f)->filename, (*f)->line_num);
888 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
889 } else {
890 fprintf(stderr, "tcc: ");
894 void error(const char *fmt, ...)
896 va_list ap;
897 va_start(ap, fmt);
898 printline();
899 vfprintf(stderr, fmt, ap);
900 fprintf(stderr, "\n");
901 exit(1);
902 va_end(ap);
905 void expect(const char *msg)
907 error("%s expected", msg);
910 void warning(const char *fmt, ...)
912 va_list ap;
914 va_start(ap, fmt);
915 printline();
916 fprintf(stderr, "warning: ");
917 vfprintf(stderr, fmt, ap);
918 fprintf(stderr, "\n");
919 va_end(ap);
922 void skip(int c)
924 if (tok != c)
925 error("'%c' expected", c);
926 next();
929 void test_lvalue(void)
931 if (!(vtop->r & VT_LVAL))
932 expect("lvalue");
935 TokenSym *tok_alloc(const char *str, int len)
937 TokenSym *ts, **pts, **ptable;
938 int h, i;
940 if (len <= 0)
941 len = strlen(str);
942 h = 1;
943 for(i=0;i<len;i++)
944 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
946 pts = &hash_ident[h];
947 while (1) {
948 ts = *pts;
949 if (!ts)
950 break;
951 if (ts->len == len && !memcmp(ts->str, str, len))
952 return ts;
953 pts = &(ts->hash_next);
956 if (tok_ident >= SYM_FIRST_ANOM)
957 error("memory full");
959 /* expand token table if needed */
960 i = tok_ident - TOK_IDENT;
961 if ((i % TOK_ALLOC_INCR) == 0) {
962 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
963 if (!ptable)
964 error("memory full");
965 table_ident = ptable;
968 ts = malloc(sizeof(TokenSym) + len);
969 if (!ts)
970 error("memory full");
971 table_ident[i] = ts;
972 ts->tok = tok_ident++;
973 ts->len = len;
974 ts->hash_next = NULL;
975 memcpy(ts->str, str, len + 1);
976 *pts = ts;
977 return ts;
980 void add_char(char **pp, int c)
982 char *p;
983 p = *pp;
984 if (c == '\'' || c == '\"' || c == '\\') {
985 /* XXX: could be more precise if char or string */
986 *p++ = '\\';
988 if (c >= 32 && c <= 126) {
989 *p++ = c;
990 } else {
991 *p++ = '\\';
992 if (c == '\n') {
993 *p++ = 'n';
994 } else {
995 *p++ = '0' + ((c >> 6) & 7);
996 *p++ = '0' + ((c >> 3) & 7);
997 *p++ = '0' + (c & 7);
1000 *pp = p;
1003 /* XXX: buffer overflow */
1004 char *get_tok_str(int v, CValue *cv)
1006 static char buf[STRING_MAX_SIZE + 1];
1007 TokenSym *ts;
1008 char *p;
1009 int i;
1011 if (v == TOK_CINT || v == TOK_CUINT) {
1012 sprintf(buf, "%u", cv->ui);
1013 return buf;
1014 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
1015 p = buf;
1016 *p++ = '\'';
1017 add_char(&p, cv->i);
1018 *p++ = '\'';
1019 *p = '\0';
1020 return buf;
1021 } else if (v == TOK_STR || v == TOK_LSTR) {
1022 ts = cv->ts;
1023 p = buf;
1024 *p++ = '\"';
1025 for(i=0;i<ts->len;i++)
1026 add_char(&p, ts->str[i]);
1027 *p++ = '\"';
1028 *p = '\0';
1029 return buf;
1030 } else if (v < TOK_IDENT) {
1031 p = buf;
1032 *p++ = v;
1033 *p = '\0';
1034 return buf;
1035 } else if (v < tok_ident) {
1036 return table_ident[v - TOK_IDENT]->str;
1037 } else if (v >= SYM_FIRST_ANOM) {
1038 /* special name for anonymous symbol */
1039 sprintf(buf, "L.%u", v - SYM_FIRST_ANOM);
1040 return buf;
1041 } else {
1042 /* should never happen */
1043 return NULL;
1047 /* push, without hashing */
1048 Sym *sym_push2(Sym **ps, int v, int t, int c)
1050 Sym *s;
1051 s = malloc(sizeof(Sym));
1052 if (!s)
1053 error("memory full");
1054 s->v = v;
1055 s->t = t;
1056 s->c = c;
1057 s->next = NULL;
1058 /* add in stack */
1059 s->prev = *ps;
1060 *ps = s;
1061 return s;
1064 /* find a symbol and return its associated structure. 's' is the top
1065 of the symbol stack */
1066 Sym *sym_find2(Sym *s, int v)
1068 while (s) {
1069 if (s->v == v)
1070 return s;
1071 s = s->prev;
1073 return NULL;
1076 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1078 /* find a symbol and return its associated structure. 'st' is the
1079 symbol stack */
1080 Sym *sym_find1(SymStack *st, int v)
1082 Sym *s;
1084 s = st->hash[HASH_SYM(v)];
1085 while (s) {
1086 if (s->v == v)
1087 return s;
1088 s = s->hash_next;
1090 return NULL;
1093 Sym *sym_push1(SymStack *st, int v, int t, int c)
1095 Sym *s, **ps;
1096 s = sym_push2(&st->top, v, t, c);
1097 /* add in hash table */
1098 if (v) {
1099 ps = &st->hash[HASH_SYM(v)];
1100 s->hash_next = *ps;
1101 *ps = s;
1103 return s;
1106 /* find a symbol in the right symbol space */
1107 Sym *sym_find(int v)
1109 Sym *s;
1110 s = sym_find1(&local_stack, v);
1111 if (!s)
1112 s = sym_find1(&global_stack, v);
1113 return s;
1116 /* push a given symbol on the symbol stack */
1117 Sym *sym_push(int v, int t, int r, int c)
1119 Sym *s;
1120 if (local_stack.top)
1121 s = sym_push1(&local_stack, v, t, c);
1122 else
1123 s = sym_push1(&global_stack, v, t, c);
1124 s->r = r;
1125 return s;
1128 /* pop symbols until top reaches 'b' */
1129 void sym_pop(SymStack *st, Sym *b)
1131 Sym *s, *ss;
1133 s = st->top;
1134 while(s != b) {
1135 ss = s->prev;
1136 /* free hash table entry, except if symbol was freed (only
1137 used for #undef symbols) */
1138 if (s->v)
1139 st->hash[HASH_SYM(s->v)] = s->hash_next;
1140 free(s);
1141 s = ss;
1143 st->top = b;
1146 /* undefined a hashed symbol (used for #undef). Its name is set to
1147 zero */
1148 void sym_undef(SymStack *st, Sym *s)
1150 Sym **ss;
1151 ss = &st->hash[HASH_SYM(s->v)];
1152 while (*ss != NULL) {
1153 if (*ss == s)
1154 break;
1155 ss = &(*ss)->hash_next;
1157 *ss = s->hash_next;
1158 s->v = 0;
1161 /* I/O layer */
1163 BufferedFile *tcc_open(const char *filename)
1165 int fd;
1166 BufferedFile *bf;
1168 fd = open(filename, O_RDONLY);
1169 if (fd < 0)
1170 return NULL;
1171 bf = malloc(sizeof(BufferedFile));
1172 if (!bf) {
1173 close(fd);
1174 return NULL;
1176 bf->fd = fd;
1177 bf->buf_ptr = bf->buffer;
1178 bf->buf_end = bf->buffer;
1179 bf->buffer[0] = CH_EOB; /* put eob symbol */
1180 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1181 bf->line_num = 1;
1182 // printf("opening '%s'\n", filename);
1183 return bf;
1186 void tcc_close(BufferedFile *bf)
1188 total_lines += bf->line_num;
1189 close(bf->fd);
1190 free(bf);
1193 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1194 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1196 /* fill input buffer and return next char */
1197 int tcc_getc_slow(BufferedFile *bf)
1199 int len;
1200 /* only tries to read if really end of buffer */
1201 if (bf->buf_ptr >= bf->buf_end) {
1202 if (bf->fd != -1) {
1203 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1204 if (len < 0)
1205 len = 0;
1206 } else {
1207 len = 0;
1209 total_bytes += len;
1210 bf->buf_ptr = bf->buffer;
1211 bf->buf_end = bf->buffer + len;
1212 *bf->buf_end = CH_EOB;
1214 if (bf->buf_ptr < bf->buf_end) {
1215 return *bf->buf_ptr++;
1216 } else {
1217 bf->buf_ptr = bf->buf_end;
1218 return CH_EOF;
1222 /* no need to put that inline */
1223 void handle_eob(void)
1225 for(;;) {
1226 ch1 = tcc_getc_slow(file);
1227 if (ch1 != CH_EOF)
1228 return;
1230 if (include_stack_ptr == include_stack)
1231 return;
1232 /* add end of include file debug info */
1233 if (do_debug) {
1234 put_stabd(N_EINCL, 0, 0);
1236 /* pop include stack */
1237 tcc_close(file);
1238 include_stack_ptr--;
1239 file = *include_stack_ptr;
1243 /* read next char from current input file */
1244 static inline void inp(void)
1246 ch1 = TCC_GETC(file);
1247 /* end of buffer/file handling */
1248 if (ch1 == CH_EOB)
1249 handle_eob();
1250 if (ch1 == '\n')
1251 file->line_num++;
1252 // printf("ch1=%c 0x%x\n", ch1, ch1);
1255 /* input with '\\n' handling */
1256 static inline void minp(void)
1258 redo:
1259 ch = ch1;
1260 inp();
1261 if (ch == '\\' && ch1 == '\n') {
1262 inp();
1263 goto redo;
1265 //printf("ch=%c 0x%x\n", ch, ch);
1269 /* same as minp, but also skip comments */
1270 void cinp(void)
1272 int c;
1274 if (ch1 == '/') {
1275 inp();
1276 if (ch1 == '/') {
1277 /* single line C++ comments */
1278 inp();
1279 while (ch1 != '\n' && ch1 != -1)
1280 inp();
1281 inp();
1282 ch = ' '; /* return space */
1283 } else if (ch1 == '*') {
1284 /* C comments */
1285 inp();
1286 while (ch1 != -1) {
1287 c = ch1;
1288 inp();
1289 if (c == '*' && ch1 == '/') {
1290 inp();
1291 ch = ' '; /* return space */
1292 break;
1295 } else {
1296 ch = '/';
1298 } else {
1299 minp();
1303 void skip_spaces(void)
1305 while (ch == ' ' || ch == '\t')
1306 cinp();
1309 /* skip block of text until #else, #elif or #endif. skip also pairs of
1310 #if/#endif */
1311 void preprocess_skip(void)
1313 int a;
1314 a = 0;
1315 while (1) {
1316 while (ch != '\n') {
1317 if (ch == -1)
1318 expect("#endif");
1319 cinp();
1321 cinp();
1322 skip_spaces();
1323 if (ch == '#') {
1324 cinp();
1325 next_nomacro();
1326 if (a == 0 &&
1327 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1328 break;
1329 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1330 a++;
1331 else if (tok == TOK_ENDIF)
1332 a--;
1337 /* ParseState handling */
1339 /* XXX: currently, no include file info is stored. Thus, we cannot display
1340 accurate messages if the function or data definition spans multiple
1341 files */
1343 /* save current parse state in 's' */
1344 void save_parse_state(ParseState *s)
1346 s->line_num = file->line_num;
1347 s->macro_ptr = macro_ptr;
1348 s->tok = tok;
1349 s->tokc = tokc;
1352 /* restore parse state from 's' */
1353 void restore_parse_state(ParseState *s)
1355 file->line_num = s->line_num;
1356 macro_ptr = s->macro_ptr;
1357 tok = s->tok;
1358 tokc = s->tokc;
1361 /* return the number of additionnal 'ints' necessary to store the
1362 token */
1363 static inline int tok_ext_size(int t)
1365 switch(t) {
1366 /* 4 bytes */
1367 case TOK_CINT:
1368 case TOK_CUINT:
1369 case TOK_CCHAR:
1370 case TOK_LCHAR:
1371 case TOK_STR:
1372 case TOK_LSTR:
1373 case TOK_CFLOAT:
1374 case TOK_LINENUM:
1375 return 1;
1376 case TOK_CDOUBLE:
1377 case TOK_CLLONG:
1378 case TOK_CULLONG:
1379 return 2;
1380 case TOK_CLDOUBLE:
1381 return LDOUBLE_SIZE / 4;
1382 default:
1383 return 0;
1387 /* token string handling */
1389 static inline void tok_str_new(TokenString *s)
1391 s->str = NULL;
1392 s->len = 0;
1393 s->last_line_num = -1;
1396 static void tok_str_add(TokenString *s, int t)
1398 int len, *str;
1400 len = s->len;
1401 str = s->str;
1402 if ((len & 63) == 0) {
1403 str = realloc(str, (len + 64) * sizeof(int));
1404 if (!str)
1405 return;
1406 s->str = str;
1408 str[len++] = t;
1409 s->len = len;
1412 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1414 int n, i;
1415 tok_str_add(s, t);
1416 n = tok_ext_size(t);
1417 for(i=0;i<n;i++)
1418 tok_str_add(s, cv->tab[i]);
1421 /* add the current parse token in token string 's' */
1422 static void tok_str_add_tok(TokenString *s)
1424 CValue cval;
1426 /* save line number info */
1427 if (file->line_num != s->last_line_num) {
1428 s->last_line_num = file->line_num;
1429 cval.i = s->last_line_num;
1430 tok_str_add2(s, TOK_LINENUM, &cval);
1432 tok_str_add2(s, tok, &tokc);
1435 /* get a token from an integer array and increment pointer accordingly */
1436 static int tok_get(int **tok_str, CValue *cv)
1438 int *p, t, n, i;
1440 p = *tok_str;
1441 t = *p++;
1442 n = tok_ext_size(t);
1443 for(i=0;i<n;i++)
1444 cv->tab[i] = *p++;
1445 *tok_str = p;
1446 return t;
1449 /* eval an expression for #if/#elif */
1450 int expr_preprocess(void)
1452 int c, t;
1453 TokenString str;
1455 tok_str_new(&str);
1456 while (1) {
1457 skip_spaces();
1458 if (ch == '\n')
1459 break;
1460 next(); /* do macro subst */
1461 if (tok == TOK_DEFINED) {
1462 next_nomacro();
1463 t = tok;
1464 if (t == '(')
1465 next_nomacro();
1466 c = sym_find1(&define_stack, tok) != 0;
1467 if (t == '(')
1468 next_nomacro();
1469 tok = TOK_CINT;
1470 tokc.i = c;
1471 } else if (tok >= TOK_IDENT) {
1472 /* if undefined macro */
1473 tok = TOK_CINT;
1474 tokc.i = 0;
1476 tok_str_add_tok(&str);
1478 tok_str_add(&str, -1); /* simulate end of file */
1479 tok_str_add(&str, 0);
1480 /* now evaluate C constant expression */
1481 macro_ptr = str.str;
1482 next();
1483 c = expr_const();
1484 macro_ptr = NULL;
1485 free(str.str);
1486 return c != 0;
1489 #if defined(DEBUG) || defined(PP_DEBUG)
1490 void tok_print(int *str)
1492 int t;
1493 CValue cval;
1495 while (1) {
1496 t = tok_get(&str, &cval);
1497 if (!t)
1498 break;
1499 printf(" %s", get_tok_str(t, &cval));
1501 printf("\n");
1503 #endif
1505 /* parse after #define */
1506 void parse_define(void)
1508 Sym *s, *first, **ps;
1509 int v, t, varg, is_vaargs;
1510 TokenString str;
1512 v = tok;
1513 /* XXX: should check if same macro (ANSI) */
1514 first = NULL;
1515 t = MACRO_OBJ;
1516 /* '(' must be just after macro definition for MACRO_FUNC */
1517 if (ch == '(') {
1518 next_nomacro();
1519 next_nomacro();
1520 ps = &first;
1521 while (tok != ')') {
1522 varg = tok;
1523 next_nomacro();
1524 is_vaargs = 0;
1525 if (varg == TOK_DOTS) {
1526 varg = TOK___VA_ARGS__;
1527 is_vaargs = 1;
1528 } else if (tok == TOK_DOTS && gnu_ext) {
1529 is_vaargs = 1;
1530 next_nomacro();
1532 if (varg < TOK_IDENT)
1533 error("badly punctuated parameter list");
1534 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1535 *ps = s;
1536 ps = &s->next;
1537 if (tok != ',')
1538 break;
1539 next_nomacro();
1541 t = MACRO_FUNC;
1543 tok_str_new(&str);
1544 while (1) {
1545 skip_spaces();
1546 if (ch == '\n' || ch == -1)
1547 break;
1548 next_nomacro();
1549 tok_str_add2(&str, tok, &tokc);
1551 tok_str_add(&str, 0);
1552 #ifdef PP_DEBUG
1553 printf("define %s %d: ", get_tok_str(v, NULL), t);
1554 tok_print(str);
1555 #endif
1556 s = sym_push1(&define_stack, v, t, (int)str.str);
1557 s->next = first;
1560 void preprocess(void)
1562 int size, i, c;
1563 char buf[1024], *q, *p;
1564 char buf1[1024];
1565 BufferedFile *f;
1566 Sym *s;
1568 cinp();
1569 next_nomacro();
1570 redo:
1571 if (tok == TOK_DEFINE) {
1572 next_nomacro();
1573 parse_define();
1574 } else if (tok == TOK_UNDEF) {
1575 next_nomacro();
1576 s = sym_find1(&define_stack, tok);
1577 /* undefine symbol by putting an invalid name */
1578 if (s)
1579 sym_undef(&define_stack, s);
1580 } else if (tok == TOK_INCLUDE) {
1581 skip_spaces();
1582 if (ch == '<') {
1583 c = '>';
1584 goto read_name;
1585 } else if (ch == '\"') {
1586 c = ch;
1587 read_name:
1588 minp();
1589 q = buf;
1590 while (ch != c && ch != '\n' && ch != -1) {
1591 if ((q - buf) < sizeof(buf) - 1)
1592 *q++ = ch;
1593 minp();
1595 *q = '\0';
1596 } else {
1597 next();
1598 if (tok != TOK_STR)
1599 error("#include syntax error");
1600 pstrcpy(buf, sizeof(buf), get_tok_str(tok, &tokc));
1601 c = '\"';
1603 /* eat all spaces and comments after include */
1604 /* XXX: slightly incorrect */
1605 while (ch1 != '\n' && ch1 != -1)
1606 inp();
1608 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1609 error("memory full");
1610 if (c == '\"') {
1611 /* first search in current dir if "header.h" */
1612 size = 0;
1613 p = strrchr(file->filename, '/');
1614 if (p)
1615 size = p + 1 - file->filename;
1616 if (size > sizeof(buf1) - 1)
1617 size = sizeof(buf1) - 1;
1618 memcpy(buf1, file->filename, size);
1619 buf1[size] = '\0';
1620 pstrcat(buf1, sizeof(buf1), buf);
1621 f = tcc_open(buf1);
1622 if (f)
1623 goto found;
1625 /* now search in standard include path */
1626 for(i=nb_include_paths - 1;i>=0;i--) {
1627 strcpy(buf1, include_paths[i]);
1628 strcat(buf1, "/");
1629 strcat(buf1, buf);
1630 f = tcc_open(buf1);
1631 if (f)
1632 goto found;
1634 error("include file '%s' not found", buf);
1635 f = NULL;
1636 found:
1637 /* push current file in stack */
1638 /* XXX: fix current line init */
1639 *include_stack_ptr++ = file;
1640 file = f;
1641 /* add include file debug info */
1642 if (do_debug) {
1643 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1645 } else if (tok == TOK_IFNDEF) {
1646 c = 1;
1647 goto do_ifdef;
1648 } else if (tok == TOK_IF) {
1649 c = expr_preprocess();
1650 goto do_if;
1651 } else if (tok == TOK_IFDEF) {
1652 c = 0;
1653 do_ifdef:
1654 next_nomacro();
1655 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1656 do_if:
1657 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1658 error("memory full");
1659 *ifdef_stack_ptr++ = c;
1660 goto test_skip;
1661 } else if (tok == TOK_ELSE) {
1662 if (ifdef_stack_ptr == ifdef_stack)
1663 error("#else without matching #if");
1664 if (ifdef_stack_ptr[-1] & 2)
1665 error("#else after #else");
1666 c = (ifdef_stack_ptr[-1] ^= 3);
1667 goto test_skip;
1668 } else if (tok == TOK_ELIF) {
1669 if (ifdef_stack_ptr == ifdef_stack)
1670 error("#elif without matching #if");
1671 c = ifdef_stack_ptr[-1];
1672 if (c > 1)
1673 error("#elif after #else");
1674 /* last #if/#elif expression was true: we skip */
1675 if (c == 1)
1676 goto skip;
1677 c = expr_preprocess();
1678 ifdef_stack_ptr[-1] = c;
1679 test_skip:
1680 if (!(c & 1)) {
1681 skip:
1682 preprocess_skip();
1683 goto redo;
1685 } else if (tok == TOK_ENDIF) {
1686 if (ifdef_stack_ptr == ifdef_stack)
1687 error("#endif without matching #if");
1688 ifdef_stack_ptr--;
1689 } else if (tok == TOK_LINE) {
1690 next();
1691 if (tok != TOK_CINT)
1692 error("#line");
1693 file->line_num = tokc.i;
1694 skip_spaces();
1695 if (ch != '\n') {
1696 next();
1697 if (tok != TOK_STR)
1698 error("#line");
1699 pstrcpy(file->filename, sizeof(file->filename),
1700 get_tok_str(tok, &tokc));
1702 } else if (tok == TOK_ERROR) {
1703 error("#error");
1705 /* ignore other preprocess commands or #! for C scripts */
1706 while (ch != '\n' && ch != -1)
1707 cinp();
1710 /* read a number in base b */
1711 int getn(b)
1713 int n, t;
1714 n = 0;
1715 while (1) {
1716 if (ch >= 'a' && ch <= 'f')
1717 t = ch - 'a' + 10;
1718 else if (ch >= 'A' && ch <= 'F')
1719 t = ch - 'A' + 10;
1720 else if (isnum(ch))
1721 t = ch - '0';
1722 else
1723 break;
1724 if (t < 0 || t >= b)
1725 break;
1726 n = n * b + t;
1727 cinp();
1729 return n;
1732 /* read a character for string or char constant and eval escape codes */
1733 int getq()
1735 int c;
1737 c = ch;
1738 minp();
1739 if (c == '\\') {
1740 if (isnum(ch)) {
1741 /* at most three octal digits */
1742 c = ch - '0';
1743 minp();
1744 if (isnum(ch)) {
1745 c = c * 8 + ch - '0';
1746 minp();
1747 if (isnum(ch)) {
1748 c = c * 8 + ch - '0';
1749 minp();
1752 return c;
1753 } else if (ch == 'x') {
1754 minp();
1755 return getn(16);
1756 } else {
1757 if (ch == 'a')
1758 c = '\a';
1759 else if (ch == 'b')
1760 c = '\b';
1761 else if (ch == 'f')
1762 c = '\f';
1763 else if (ch == 'n')
1764 c = '\n';
1765 else if (ch == 'r')
1766 c = '\r';
1767 else if (ch == 't')
1768 c = '\t';
1769 else if (ch == 'v')
1770 c = '\v';
1771 else if (ch == 'e' && gnu_ext)
1772 c = 27;
1773 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1774 c = ch;
1775 else
1776 error("invalid escaped char");
1777 minp();
1780 return c;
1783 /* we use 64 bit numbers */
1784 #define BN_SIZE 2
1786 /* bn = (bn << shift) | or_val */
1787 void bn_lshift(unsigned int *bn, int shift, int or_val)
1789 int i;
1790 unsigned int v;
1791 for(i=0;i<BN_SIZE;i++) {
1792 v = bn[i];
1793 bn[i] = (v << shift) | or_val;
1794 or_val = v >> (32 - shift);
1798 void bn_zero(unsigned int *bn)
1800 int i;
1801 for(i=0;i<BN_SIZE;i++) {
1802 bn[i] = 0;
1806 void parse_number(void)
1808 int b, t, shift, frac_bits, s, exp_val;
1809 char *q;
1810 unsigned int bn[BN_SIZE];
1811 double d;
1813 /* number */
1814 q = token_buf;
1815 t = ch;
1816 cinp();
1817 *q++ = t;
1818 b = 10;
1819 if (t == '.') {
1820 /* special dot handling */
1821 if (ch >= '0' && ch <= '9') {
1822 goto float_frac_parse;
1823 } else if (ch == '.') {
1824 cinp();
1825 if (ch != '.')
1826 expect("'.'");
1827 cinp();
1828 tok = TOK_DOTS;
1829 } else {
1830 /* dots */
1831 tok = t;
1833 return;
1834 } else if (t == '0') {
1835 if (ch == 'x' || ch == 'X') {
1836 q--;
1837 cinp();
1838 b = 16;
1839 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1840 q--;
1841 cinp();
1842 b = 2;
1845 /* parse all digits. cannot check octal numbers at this stage
1846 because of floating point constants */
1847 while (1) {
1848 if (ch >= 'a' && ch <= 'f')
1849 t = ch - 'a' + 10;
1850 else if (ch >= 'A' && ch <= 'F')
1851 t = ch - 'A' + 10;
1852 else if (isnum(ch))
1853 t = ch - '0';
1854 else
1855 break;
1856 if (t >= b)
1857 break;
1858 if (q >= token_buf + STRING_MAX_SIZE) {
1859 num_too_long:
1860 error("number too long");
1862 *q++ = ch;
1863 cinp();
1865 if (ch == '.' ||
1866 ((ch == 'e' || ch == 'E') && b == 10) ||
1867 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1868 if (b != 10) {
1869 /* NOTE: strtox should support that for hexa numbers, but
1870 non ISOC99 libcs do not support it, so we prefer to do
1871 it by hand */
1872 /* hexadecimal or binary floats */
1873 /* XXX: handle overflows */
1874 *q = '\0';
1875 if (b == 16)
1876 shift = 4;
1877 else
1878 shift = 2;
1879 bn_zero(bn);
1880 q = token_buf;
1881 while (1) {
1882 t = *q++;
1883 if (t == '\0') {
1884 break;
1885 } else if (t >= 'a') {
1886 t = t - 'a' + 10;
1887 } else if (t >= 'A') {
1888 t = t - 'A' + 10;
1889 } else {
1890 t = t - '0';
1892 bn_lshift(bn, shift, t);
1894 frac_bits = 0;
1895 if (ch == '.') {
1896 cinp();
1897 while (1) {
1898 t = ch;
1899 if (t >= 'a' && t <= 'f') {
1900 t = t - 'a' + 10;
1901 } else if (t >= 'A' && t <= 'F') {
1902 t = t - 'A' + 10;
1903 } else if (t >= '0' && t <= '9') {
1904 t = t - '0';
1905 } else {
1906 break;
1908 if (t >= b)
1909 error("invalid digit");
1910 bn_lshift(bn, shift, t);
1911 frac_bits += shift;
1912 cinp();
1915 if (ch != 'p' && ch != 'P')
1916 error("exponent expected");
1917 cinp();
1918 s = 1;
1919 exp_val = 0;
1920 if (ch == '+') {
1921 cinp();
1922 } else if (ch == '-') {
1923 s = -1;
1924 cinp();
1926 if (ch < '0' || ch > '9')
1927 error("exponent digits expected");
1928 while (ch >= '0' && ch <= '9') {
1929 exp_val = exp_val * 10 + ch - '0';
1930 cinp();
1932 exp_val = exp_val * s;
1934 /* now we can generate the number */
1935 /* XXX: should patch directly float number */
1936 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1937 d = ldexp(d, exp_val - frac_bits);
1938 t = toup(ch);
1939 if (t == 'F') {
1940 cinp();
1941 tok = TOK_CFLOAT;
1942 /* float : should handle overflow */
1943 tokc.f = (float)d;
1944 } else if (t == 'L') {
1945 cinp();
1946 tok = TOK_CLDOUBLE;
1947 /* XXX: not large enough */
1948 tokc.ld = (long double)d;
1949 } else {
1950 tok = TOK_CDOUBLE;
1951 tokc.d = d;
1953 } else {
1954 /* decimal floats */
1955 if (ch == '.') {
1956 if (q >= token_buf + STRING_MAX_SIZE)
1957 goto num_too_long;
1958 *q++ = ch;
1959 cinp();
1960 float_frac_parse:
1961 while (ch >= '0' && ch <= '9') {
1962 if (q >= token_buf + STRING_MAX_SIZE)
1963 goto num_too_long;
1964 *q++ = ch;
1965 cinp();
1968 if (ch == 'e' || ch == 'E') {
1969 if (q >= token_buf + STRING_MAX_SIZE)
1970 goto num_too_long;
1971 *q++ = ch;
1972 cinp();
1973 if (ch == '-' || ch == '+') {
1974 if (q >= token_buf + STRING_MAX_SIZE)
1975 goto num_too_long;
1976 *q++ = ch;
1977 cinp();
1979 if (ch < '0' || ch > '9')
1980 error("exponent digits expected");
1981 while (ch >= '0' && ch <= '9') {
1982 if (q >= token_buf + STRING_MAX_SIZE)
1983 goto num_too_long;
1984 *q++ = ch;
1985 cinp();
1988 *q = '\0';
1989 t = toup(ch);
1990 errno = 0;
1991 if (t == 'F') {
1992 cinp();
1993 tok = TOK_CFLOAT;
1994 tokc.f = strtof(token_buf, NULL);
1995 } else if (t == 'L') {
1996 cinp();
1997 tok = TOK_CLDOUBLE;
1998 tokc.ld = strtold(token_buf, NULL);
1999 } else {
2000 tok = TOK_CDOUBLE;
2001 tokc.d = strtod(token_buf, NULL);
2004 } else {
2005 unsigned long long n, n1;
2006 int lcount;
2008 /* integer number */
2009 *q = '\0';
2010 q = token_buf;
2011 if (b == 10 && *q == '0') {
2012 b = 8;
2013 q++;
2015 n = 0;
2016 while(1) {
2017 t = *q++;
2018 /* no need for checks except for base 10 / 8 errors */
2019 if (t == '\0') {
2020 break;
2021 } else if (t >= 'a') {
2022 t = t - 'a' + 10;
2023 } else if (t >= 'A') {
2024 t = t - 'A' + 10;
2025 } else {
2026 t = t - '0';
2027 if (t >= b)
2028 error("invalid digit");
2030 n1 = n;
2031 n = n * b + t;
2032 /* detect overflow */
2033 if (n < n1)
2034 error("integer constant overflow");
2037 /* XXX: not exactly ANSI compliant */
2038 if ((n & 0xffffffff00000000LL) != 0) {
2039 if ((n >> 63) != 0)
2040 tok = TOK_CULLONG;
2041 else
2042 tok = TOK_CLLONG;
2043 } else if (n > 0x7fffffff) {
2044 tok = TOK_CUINT;
2045 } else {
2046 tok = TOK_CINT;
2048 lcount = 0;
2049 for(;;) {
2050 t = toup(ch);
2051 if (t == 'L') {
2052 if (lcount >= 2)
2053 error("three 'l' in integer constant");
2054 lcount++;
2055 if (lcount == 2) {
2056 if (tok == TOK_CINT)
2057 tok = TOK_CLLONG;
2058 else if (tok == TOK_CUINT)
2059 tok = TOK_CULLONG;
2061 cinp();
2062 } else if (t == 'U') {
2063 if (tok == TOK_CINT)
2064 tok = TOK_CUINT;
2065 else if (tok == TOK_CLLONG)
2066 tok = TOK_CULLONG;
2067 cinp();
2068 } else {
2069 break;
2072 if (tok == TOK_CINT || tok == TOK_CUINT)
2073 tokc.ui = n;
2074 else
2075 tokc.ull = n;
2080 /* return next token without macro substitution */
2081 void next_nomacro1(void)
2083 int b;
2084 char *q;
2085 TokenSym *ts;
2087 /* skip spaces */
2088 while(1) {
2089 while (ch == '\n') {
2090 cinp();
2091 while (ch == ' ' || ch == '\t')
2092 cinp();
2093 if (ch == '#') {
2094 /* preprocessor command if # at start of line after
2095 spaces */
2096 preprocess();
2099 if (ch != ' ' && ch != '\t' && ch != '\f')
2100 break;
2101 cinp();
2103 if (isid(ch)) {
2104 q = token_buf;
2105 *q++ = ch;
2106 cinp();
2107 if (q[-1] == 'L') {
2108 if (ch == '\'') {
2109 tok = TOK_LCHAR;
2110 goto char_const;
2112 if (ch == '\"') {
2113 tok = TOK_LSTR;
2114 goto str_const;
2117 while (isid(ch) || isnum(ch)) {
2118 if (q >= token_buf + STRING_MAX_SIZE)
2119 error("ident too long");
2120 *q++ = ch;
2121 cinp();
2123 *q = '\0';
2124 ts = tok_alloc(token_buf, q - token_buf);
2125 tok = ts->tok;
2126 } else if (isnum(ch) || ch == '.') {
2127 parse_number();
2128 } else if (ch == '\'') {
2129 tok = TOK_CCHAR;
2130 char_const:
2131 minp();
2132 tokc.i = getq();
2133 if (ch != '\'')
2134 expect("\'");
2135 minp();
2136 } else if (ch == '\"') {
2137 tok = TOK_STR;
2138 str_const:
2139 minp();
2140 q = token_buf;
2141 while (ch != '\"') {
2142 b = getq();
2143 if (ch == -1)
2144 error("unterminated string");
2145 if (q >= token_buf + STRING_MAX_SIZE)
2146 error("string too long");
2147 *q++ = b;
2149 *q = '\0';
2150 tokc.ts = tok_alloc(token_buf, q - token_buf);
2151 minp();
2152 } else {
2153 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2154 /* two chars */
2155 tok = ch;
2156 cinp();
2157 while (*q) {
2158 if (*q == tok && q[1] == ch) {
2159 cinp();
2160 tok = q[2] & 0xff;
2161 /* three chars tests */
2162 if (tok == TOK_SHL || tok == TOK_SAR) {
2163 if (ch == '=') {
2164 tok = tok | 0x80;
2165 cinp();
2167 } else if (tok == TOK_DOTS) {
2168 if (ch != '.')
2169 error("parse error");
2170 cinp();
2172 return;
2174 q = q + 3;
2176 /* single char substitutions */
2177 if (tok == '<')
2178 tok = TOK_LT;
2179 else if (tok == '>')
2180 tok = TOK_GT;
2184 /* return next token without macro substitution. Can read input from
2185 macro_ptr buffer */
2186 void next_nomacro()
2188 if (macro_ptr) {
2189 redo:
2190 tok = *macro_ptr;
2191 if (tok) {
2192 tok = tok_get(&macro_ptr, &tokc);
2193 if (tok == TOK_LINENUM) {
2194 file->line_num = tokc.i;
2195 goto redo;
2198 } else {
2199 next_nomacro1();
2203 /* substitute args in macro_str and return allocated string */
2204 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2206 int *st, last_tok, t, notfirst;
2207 Sym *s;
2208 TokenSym *ts;
2209 CValue cval;
2210 TokenString str;
2212 tok_str_new(&str);
2213 last_tok = 0;
2214 while(1) {
2215 t = tok_get(&macro_str, &cval);
2216 if (!t)
2217 break;
2218 if (t == '#') {
2219 /* stringize */
2220 t = tok_get(&macro_str, &cval);
2221 if (!t)
2222 break;
2223 s = sym_find2(args, t);
2224 if (s) {
2225 token_buf[0] = '\0';
2226 st = (int *)s->c;
2227 notfirst = 0;
2228 while (*st) {
2229 if (notfirst)
2230 pstrcat(token_buf, sizeof(token_buf), " ");
2231 t = tok_get(&st, &cval);
2232 pstrcat(token_buf, sizeof(token_buf), get_tok_str(t, &cval));
2233 notfirst = 1;
2235 #ifdef PP_DEBUG
2236 printf("stringize: %s\n", token_buf);
2237 #endif
2238 /* add string */
2239 ts = tok_alloc(token_buf, 0);
2240 cval.ts = ts;
2241 tok_str_add2(&str, TOK_STR, &cval);
2242 } else {
2243 tok_str_add2(&str, t, &cval);
2245 } else if (t >= TOK_IDENT) {
2246 s = sym_find2(args, t);
2247 if (s) {
2248 st = (int *)s->c;
2249 /* if '##' is present before or after, no arg substitution */
2250 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2251 /* special case for var arg macros : ## eats the
2252 ',' if empty VA_ARGS riable. */
2253 /* XXX: test of the ',' is not 100%
2254 reliable. should fix it to avoid security
2255 problems */
2256 if (gnu_ext && s->t && *st == 0 &&
2257 last_tok == TOK_TWOSHARPS &&
2258 str.len >= 2&& str.str[str.len - 2] == ',') {
2259 /* suppress ',' '##' */
2260 str.len -= 2;
2261 } else {
2262 while (*st)
2263 tok_str_add(&str, *st++);
2265 } else {
2266 macro_subst(&str, nested_list, st);
2268 } else {
2269 tok_str_add(&str, t);
2271 } else {
2272 tok_str_add2(&str, t, &cval);
2274 last_tok = t;
2276 tok_str_add(&str, 0);
2277 return str.str;
2280 /* handle the '##' operator */
2281 int *macro_twosharps(int *macro_str)
2283 TokenSym *ts;
2284 int *macro_ptr1;
2285 int t;
2286 char *p;
2287 CValue cval;
2288 TokenString macro_str1;
2290 tok_str_new(&macro_str1);
2291 tok = 0;
2292 while (1) {
2293 next_nomacro();
2294 if (tok == 0)
2295 break;
2296 while (*macro_ptr == TOK_TWOSHARPS) {
2297 macro_ptr++;
2298 macro_ptr1 = macro_ptr;
2299 t = *macro_ptr;
2300 if (t) {
2301 t = tok_get(&macro_ptr, &cval);
2302 /* XXX: we handle only most common cases:
2303 ident + ident or ident + number */
2304 if (tok >= TOK_IDENT &&
2305 (t >= TOK_IDENT || t == TOK_CINT)) {
2306 p = get_tok_str(tok, &tokc);
2307 pstrcpy(token_buf, sizeof(token_buf), p);
2308 p = get_tok_str(t, &cval);
2309 pstrcat(token_buf, sizeof(token_buf), p);
2310 ts = tok_alloc(token_buf, 0);
2311 tok = ts->tok; /* modify current token */
2312 } else {
2313 /* cannot merge tokens: skip '##' */
2314 macro_ptr = macro_ptr1;
2315 break;
2319 tok_str_add2(&macro_str1, tok, &tokc);
2321 tok_str_add(&macro_str1, 0);
2322 return macro_str1.str;
2325 /* do macro substitution of macro_str and add result to
2326 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2327 substituted. 'nested_list' is the list of all macros we got inside
2328 to avoid recursing. */
2329 void macro_subst(TokenString *tok_str,
2330 Sym **nested_list, int *macro_str)
2332 Sym *s, *args, *sa, *sa1;
2333 int parlevel, *mstr, t, *saved_macro_ptr;
2334 int mstr_allocated, *macro_str1;
2335 CValue cval;
2336 TokenString str;
2338 saved_macro_ptr = macro_ptr;
2339 macro_ptr = macro_str;
2340 macro_str1 = NULL;
2341 if (macro_str) {
2342 /* first scan for '##' operator handling */
2343 macro_str1 = macro_twosharps(macro_str);
2344 macro_ptr = macro_str1;
2347 while (1) {
2348 next_nomacro();
2349 if (tok == 0)
2350 break;
2351 /* special macros */
2352 if (tok == TOK___LINE__) {
2353 cval.i = file->line_num;
2354 tok_str_add2(tok_str, TOK_CINT, &cval);
2355 } else if (tok == TOK___FILE__) {
2356 cval.ts = tok_alloc(file->filename, 0);
2357 tok_str_add2(tok_str, TOK_STR, &cval);
2358 } else if (tok == TOK___DATE__) {
2359 cval.ts = tok_alloc("Jan 1 1970", 0);
2360 tok_str_add2(tok_str, TOK_STR, &cval);
2361 } else if (tok == TOK___TIME__) {
2362 cval.ts = tok_alloc("00:00:00", 0);
2363 tok_str_add2(tok_str, TOK_STR, &cval);
2364 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
2365 /* if symbol is a macro, prepare substitution */
2366 /* if nested substitution, do nothing */
2367 if (sym_find2(*nested_list, tok))
2368 goto no_subst;
2369 mstr = (int *)s->c;
2370 mstr_allocated = 0;
2371 if (s->t == MACRO_FUNC) {
2372 /* NOTE: we do not use next_nomacro to avoid eating the
2373 next token. XXX: find better solution */
2374 if (macro_ptr) {
2375 t = *macro_ptr;
2376 } else {
2377 while (ch == ' ' || ch == '\t' || ch == '\n')
2378 cinp();
2379 t = ch;
2381 if (t != '(') /* no macro subst */
2382 goto no_subst;
2384 /* argument macro */
2385 next_nomacro();
2386 next_nomacro();
2387 args = NULL;
2388 sa = s->next;
2389 /* NOTE: empty args are allowed, except if no args */
2390 for(;;) {
2391 /* handle '()' case */
2392 if (!args && tok == ')')
2393 break;
2394 if (!sa)
2395 error("macro '%s' used with too many args",
2396 get_tok_str(s->v, 0));
2397 tok_str_new(&str);
2398 parlevel = 0;
2399 /* NOTE: non zero sa->t indicates VA_ARGS */
2400 while ((parlevel > 0 ||
2401 (tok != ')' &&
2402 (tok != ',' || sa->t))) &&
2403 tok != -1) {
2404 if (tok == '(')
2405 parlevel++;
2406 else if (tok == ')')
2407 parlevel--;
2408 tok_str_add2(&str, tok, &tokc);
2409 next_nomacro();
2411 tok_str_add(&str, 0);
2412 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2413 sa = sa->next;
2414 if (tok == ')') {
2415 /* special case for gcc var args: add an empty
2416 var arg argument if it is omitted */
2417 if (sa && sa->t && gnu_ext)
2418 continue;
2419 else
2420 break;
2422 if (tok != ',')
2423 expect(",");
2424 next_nomacro();
2426 if (sa) {
2427 error("macro '%s' used with too few args",
2428 get_tok_str(s->v, 0));
2431 /* now subst each arg */
2432 mstr = macro_arg_subst(nested_list, mstr, args);
2433 /* free memory */
2434 sa = args;
2435 while (sa) {
2436 sa1 = sa->prev;
2437 free((int *)sa->c);
2438 free(sa);
2439 sa = sa1;
2441 mstr_allocated = 1;
2443 sym_push2(nested_list, s->v, 0, 0);
2444 macro_subst(tok_str, nested_list, mstr);
2445 /* pop nested defined symbol */
2446 sa1 = *nested_list;
2447 *nested_list = sa1->prev;
2448 free(sa1);
2449 if (mstr_allocated)
2450 free(mstr);
2451 } else {
2452 no_subst:
2453 /* no need to add if reading input stream */
2454 if (!macro_str)
2455 return;
2456 tok_str_add2(tok_str, tok, &tokc);
2458 /* only replace one macro while parsing input stream */
2459 if (!macro_str)
2460 return;
2462 macro_ptr = saved_macro_ptr;
2463 if (macro_str1)
2464 free(macro_str1);
2467 /* return next token with macro substitution */
2468 void next(void)
2470 Sym *nested_list;
2471 TokenString str;
2473 /* special 'ungettok' case for label parsing */
2474 if (tok1) {
2475 tok = tok1;
2476 tokc = tok1c;
2477 tok1 = 0;
2478 } else {
2479 redo:
2480 if (!macro_ptr) {
2481 /* if not reading from macro substituted string, then try
2482 to substitute */
2483 /* XXX: optimize non macro case */
2484 tok_str_new(&str);
2485 nested_list = NULL;
2486 macro_subst(&str, &nested_list, NULL);
2487 if (str.str) {
2488 tok_str_add(&str, 0);
2489 macro_ptr = str.str;
2490 macro_ptr_allocated = str.str;
2491 goto redo;
2493 if (tok == 0)
2494 goto redo;
2495 } else {
2496 next_nomacro();
2497 if (tok == 0) {
2498 /* end of macro string: free it */
2499 free(macro_ptr_allocated);
2500 macro_ptr = NULL;
2501 goto redo;
2505 #if defined(DEBUG)
2506 printf("token = %s\n", get_tok_str(tok, tokc));
2507 #endif
2510 void swap(int *p, int *q)
2512 int t;
2513 t = *p;
2514 *p = *q;
2515 *q = t;
2518 void vsetc(int t, int r, CValue *vc)
2520 if (vtop >= vstack + VSTACK_SIZE)
2521 error("memory full");
2522 /* cannot let cpu flags if other instruction are generated */
2523 /* XXX: VT_JMP test too ? */
2524 if ((vtop->r & VT_VALMASK) == VT_CMP)
2525 gv(RC_INT);
2526 vtop++;
2527 vtop->t = t;
2528 vtop->r = r;
2529 vtop->r2 = VT_CONST;
2530 vtop->c = *vc;
2533 /* push integer constant */
2534 void vpushi(int v)
2536 CValue cval;
2537 cval.i = v;
2538 vsetc(VT_INT, VT_CONST, &cval);
2541 /* push a reference to a section offset by adding a dummy symbol */
2542 void vpush_ref(int t, Section *sec, unsigned long offset)
2544 int v;
2545 Sym *sym;
2546 CValue cval;
2548 v = anon_sym++;
2549 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2550 sym->r = VT_CONST | VT_SYM;
2551 put_extern_sym(sym, sec, offset);
2552 cval.sym = sym;
2553 vsetc(t, VT_CONST | VT_SYM, &cval);
2556 void vset(int t, int r, int v)
2558 CValue cval;
2560 cval.i = v;
2561 vsetc(t, r, &cval);
2564 void vswap(void)
2566 SValue tmp;
2568 tmp = vtop[0];
2569 vtop[0] = vtop[-1];
2570 vtop[-1] = tmp;
2573 void vpushv(SValue *v)
2575 if (vtop >= vstack + VSTACK_SIZE)
2576 error("memory full");
2577 vtop++;
2578 *vtop = *v;
2581 void vdup(void)
2583 vpushv(vtop);
2586 /* save r to the memory stack, and mark it as being free */
2587 void save_reg(int r)
2589 int l, i, saved, t, size, align;
2590 SValue *p, sv;
2592 /* modify all stack values */
2593 saved = 0;
2594 l = 0;
2595 for(p=vstack;p<=vtop;p++) {
2596 i = p->r & VT_VALMASK;
2597 if ((p->r & VT_VALMASK) == r ||
2598 (p->r2 & VT_VALMASK) == r) {
2599 /* must save value on stack if not already done */
2600 if (!saved) {
2601 /* store register in the stack */
2602 t = p->t;
2603 if ((p->r & VT_LVAL) ||
2604 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
2605 t = VT_INT;
2606 size = type_size(t, &align);
2607 loc = (loc - size) & -align;
2608 sv.t = t;
2609 sv.r = VT_LOCAL | VT_LVAL;
2610 sv.c.ul = loc;
2611 store(r, &sv);
2612 #ifdef TCC_TARGET_I386
2613 /* x86 specific: need to pop fp register ST0 if saved */
2614 if (r == REG_ST0) {
2615 o(0xd9dd); /* fstp %st(1) */
2617 #endif
2618 /* special long long case */
2619 if ((t & VT_BTYPE) == VT_LLONG) {
2620 sv.c.ul += 4;
2621 store(p->r2, &sv);
2623 l = loc;
2624 saved = 1;
2626 /* mark that stack entry as being saved on the stack */
2627 if (p->r & VT_LVAL)
2628 t = VT_LLOCAL;
2629 else
2630 t = VT_LOCAL;
2631 p->r = VT_LVAL | t;
2632 p->r2 = VT_CONST;
2633 p->c.ul = l;
2638 /* find a free register of class 'rc'. If none, save one register */
2639 int get_reg(int rc)
2641 int r;
2642 SValue *p;
2644 /* find a free register */
2645 for(r=0;r<NB_REGS;r++) {
2646 if (reg_classes[r] & rc) {
2647 for(p=vstack;p<=vtop;p++) {
2648 if ((p->r & VT_VALMASK) == r ||
2649 (p->r2 & VT_VALMASK) == r)
2650 goto notfound;
2652 return r;
2654 notfound: ;
2657 /* no register left : free the first one on the stack (VERY
2658 IMPORTANT to start from the bottom to ensure that we don't
2659 spill registers used in gen_opi()) */
2660 for(p=vstack;p<=vtop;p++) {
2661 r = p->r & VT_VALMASK;
2662 if (r < VT_CONST && (reg_classes[r] & rc)) {
2663 save_reg(r);
2664 break;
2667 return r;
2670 /* save registers up to (vtop - n) stack entry */
2671 void save_regs(int n)
2673 int r;
2674 SValue *p, *p1;
2675 p1 = vtop - n;
2676 for(p = vstack;p <= p1; p++) {
2677 r = p->r & VT_VALMASK;
2678 if (r < VT_CONST) {
2679 save_reg(r);
2684 /* move register 's' to 'r', and flush previous value of r to memory
2685 if needed */
2686 void move_reg(int r, int s)
2688 SValue sv;
2690 if (r != s) {
2691 save_reg(r);
2692 sv.t = VT_INT;
2693 sv.r = s;
2694 sv.c.ul = 0;
2695 load(r, &sv);
2699 /* get address of vtop (vtop MUST BE an lvalue) */
2700 void gaddrof(void)
2702 vtop->r &= ~VT_LVAL;
2703 /* tricky: if saved lvalue, then we can go back to lvalue */
2704 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
2705 vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
2708 #ifdef CONFIG_TCC_BCHECK
2709 /* generate lvalue bound code */
2710 void gbound(void)
2712 int lval_type;
2714 vtop->r &= ~VT_MUSTBOUND;
2715 /* if lvalue, then use checking code before dereferencing */
2716 if (vtop->r & VT_LVAL) {
2717 /* if not VT_BOUNDED value, then make one */
2718 if (!(vtop->r & VT_BOUNDED)) {
2719 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
2720 gaddrof();
2721 vpushi(0);
2722 gen_bounded_ptr_add();
2723 vtop->r |= lval_type;
2725 /* then check for dereferencing */
2726 gen_bounded_ptr_deref();
2729 #endif
2731 /* store vtop a register belonging to class 'rc'. lvalues are
2732 converted to values. Cannot be used if cannot be converted to
2733 register value (such as structures). */
2734 int gv(int rc)
2736 int r, r2, rc2, bit_pos, bit_size, size, align, i, data_offset;
2737 unsigned long long ll;
2739 /* NOTE: get_reg can modify vstack[] */
2740 if (vtop->t & VT_BITFIELD) {
2741 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
2742 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2743 /* remove bit field info to avoid loops */
2744 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2745 /* generate shifts */
2746 vpushi(32 - (bit_pos + bit_size));
2747 gen_op(TOK_SHL);
2748 vpushi(32 - bit_size);
2749 /* NOTE: transformed to SHR if unsigned */
2750 gen_op(TOK_SAR);
2751 r = gv(rc);
2752 } else {
2753 if (is_float(vtop->t) &&
2754 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2755 int v;
2756 Sym *sym;
2758 /* XXX: unify with initializers handling ? */
2759 /* CPUs usually cannot use float constants, so we store them
2760 generically in data segment */
2761 size = type_size(vtop->t, &align);
2762 data_offset = data_section->data_ptr - data_section->data;
2763 data_offset = (data_offset + align - 1) & -align;
2764 /* XXX: not portable yet */
2765 size = size >> 2;
2766 for(i=0;i<size;i++)
2767 ((int *)(data_section->data + data_offset))[i] = vtop->c.tab[i];
2769 v = anon_sym++;
2770 sym = sym_push1(&global_stack, v, vtop->t | VT_STATIC, 0);
2771 sym->r = VT_CONST | VT_SYM;
2772 put_extern_sym(sym, data_section, data_offset);
2774 vtop->r |= VT_LVAL | VT_SYM;
2775 vtop->c.sym = sym;
2776 data_offset += size << 2;
2777 data_section->data_ptr = data_section->data + data_offset;
2779 #ifdef CONFIG_TCC_BCHECK
2780 if (vtop->r & VT_MUSTBOUND)
2781 gbound();
2782 #endif
2784 r = vtop->r & VT_VALMASK;
2785 /* need to reload if:
2786 - constant
2787 - lvalue (need to dereference pointer)
2788 - already a register, but not in the right class */
2789 if (r >= VT_CONST ||
2790 (vtop->r & VT_LVAL) ||
2791 !(reg_classes[r] & rc) ||
2792 ((vtop->t & VT_BTYPE) == VT_LLONG &&
2793 !(reg_classes[vtop->r2] & rc))) {
2794 r = get_reg(rc);
2795 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
2796 /* two register type load : expand to two words
2797 temporarily */
2798 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2799 /* load constant */
2800 ll = vtop->c.ull;
2801 vtop->c.ui = ll; /* first word */
2802 load(r, vtop);
2803 vtop->r = r; /* save register value */
2804 vpushi(ll >> 32); /* second word */
2805 } else if (r >= VT_CONST ||
2806 (vtop->r & VT_LVAL)) {
2807 /* load from memory */
2808 load(r, vtop);
2809 vdup();
2810 vtop[-1].r = r; /* save register value */
2811 /* increment pointer to get second word */
2812 vtop->t = VT_INT;
2813 gaddrof();
2814 vpushi(4);
2815 gen_op('+');
2816 vtop->r |= VT_LVAL;
2817 } else {
2818 /* move registers */
2819 load(r, vtop);
2820 vdup();
2821 vtop[-1].r = r; /* save register value */
2822 vtop->r = vtop[-1].r2;
2824 /* allocate second register */
2825 rc2 = RC_INT;
2826 if (rc == RC_IRET)
2827 rc2 = RC_LRET;
2828 r2 = get_reg(rc2);
2829 load(r2, vtop);
2830 vpop();
2831 /* write second register */
2832 vtop->r2 = r2;
2833 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
2834 int t1, t;
2835 /* lvalue of scalar type : need to use lvalue type
2836 because of possible cast */
2837 t = vtop->t;
2838 t1 = t;
2839 /* compute memory access type */
2840 if (vtop->r & VT_LVAL_BYTE)
2841 t = VT_BYTE;
2842 else if (vtop->r & VT_LVAL_SHORT)
2843 t = VT_SHORT;
2844 if (vtop->r & VT_LVAL_UNSIGNED)
2845 t |= VT_UNSIGNED;
2846 vtop->t = t;
2847 load(r, vtop);
2848 /* restore wanted type */
2849 vtop->t = t1;
2850 } else {
2851 /* one register type load */
2852 load(r, vtop);
2855 vtop->r = r;
2857 return r;
2860 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2861 void gv2(int rc1, int rc2)
2863 /* generate more generic register first */
2864 if (rc1 <= rc2) {
2865 vswap();
2866 gv(rc1);
2867 vswap();
2868 gv(rc2);
2869 /* test if reload is needed for first register */
2870 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2871 vswap();
2872 gv(rc1);
2873 vswap();
2875 } else {
2876 gv(rc2);
2877 vswap();
2878 gv(rc1);
2879 vswap();
2880 /* test if reload is needed for first register */
2881 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2882 gv(rc2);
2887 /* expand long long on stack in two int registers */
2888 void lexpand(void)
2890 int u;
2892 u = vtop->t & VT_UNSIGNED;
2893 gv(RC_INT);
2894 vdup();
2895 vtop[0].r = vtop[-1].r2;
2896 vtop[0].r2 = VT_CONST;
2897 vtop[-1].r2 = VT_CONST;
2898 vtop[0].t = VT_INT | u;
2899 vtop[-1].t = VT_INT | u;
2902 /* build a long long from two ints */
2903 void lbuild(int t)
2905 gv2(RC_INT, RC_INT);
2906 vtop[-1].r2 = vtop[0].r;
2907 vtop[-1].t = t;
2908 vpop();
2911 /* rotate n first stack elements to the bottom */
2912 void vrotb(int n)
2914 int i;
2915 SValue tmp;
2917 tmp = vtop[-n + 1];
2918 for(i=-n+1;i!=0;i++)
2919 vtop[i] = vtop[i+1];
2920 vtop[0] = tmp;
2923 /* pop stack value */
2924 void vpop(void)
2926 int v;
2927 v = vtop->r & VT_VALMASK;
2928 #ifdef TCC_TARGET_I386
2929 /* for x86, we need to pop the FP stack */
2930 if (v == REG_ST0) {
2931 o(0xd9dd); /* fstp %st(1) */
2932 } else
2933 #endif
2934 if (v == VT_JMP || v == VT_JMPI) {
2935 /* need to put correct jump if && or || without test */
2936 gsym(vtop->c.ul);
2938 vtop--;
2941 /* convert stack entry to register and duplicate its value in another
2942 register */
2943 void gv_dup(void)
2945 int rc, t, r, r1;
2946 SValue sv;
2948 t = vtop->t;
2949 if ((t & VT_BTYPE) == VT_LLONG) {
2950 lexpand();
2951 gv_dup();
2952 vswap();
2953 vrotb(3);
2954 gv_dup();
2955 vrotb(4);
2956 /* stack: H L L1 H1 */
2957 lbuild(t);
2958 vrotb(3);
2959 vrotb(3);
2960 vswap();
2961 lbuild(t);
2962 vswap();
2963 } else {
2964 /* duplicate value */
2965 rc = RC_INT;
2966 sv.t = VT_INT;
2967 if (is_float(t)) {
2968 rc = RC_FLOAT;
2969 sv.t = t;
2971 r = gv(rc);
2972 r1 = get_reg(rc);
2973 sv.r = r;
2974 sv.c.ul = 0;
2975 load(r1, &sv); /* move r to r1 */
2976 vdup();
2977 /* duplicates value */
2978 vtop->r = r1;
2982 /* generate CPU independent (unsigned) long long operations */
2983 void gen_opl(int op)
2985 int t, a, b, op1, c, i;
2986 void *func;
2987 GFuncContext gf;
2988 SValue tmp;
2990 switch(op) {
2991 case '/':
2992 case TOK_PDIV:
2993 func = __divll;
2994 goto gen_func;
2995 case TOK_UDIV:
2996 func = __divull;
2997 goto gen_func;
2998 case '%':
2999 func = __modll;
3000 goto gen_func;
3001 case TOK_UMOD:
3002 func = __modull;
3003 gen_func:
3004 /* call generic long long function */
3005 gfunc_start(&gf, FUNC_CDECL);
3006 gfunc_param(&gf);
3007 gfunc_param(&gf);
3008 vpushi((int)func);
3009 gfunc_call(&gf);
3010 vpushi(0);
3011 vtop->r = REG_IRET;
3012 vtop->r2 = REG_LRET;
3013 break;
3014 case '^':
3015 case '&':
3016 case '|':
3017 case '*':
3018 case '+':
3019 case '-':
3020 t = vtop->t;
3021 vswap();
3022 lexpand();
3023 vrotb(3);
3024 lexpand();
3025 /* stack: L1 H1 L2 H2 */
3026 tmp = vtop[0];
3027 vtop[0] = vtop[-3];
3028 vtop[-3] = tmp;
3029 tmp = vtop[-2];
3030 vtop[-2] = vtop[-3];
3031 vtop[-3] = tmp;
3032 vswap();
3033 /* stack: H1 H2 L1 L2 */
3034 if (op == '*') {
3035 vpushv(vtop - 1);
3036 vpushv(vtop - 1);
3037 gen_op(TOK_UMULL);
3038 lexpand();
3039 /* stack: H1 H2 L1 L2 ML MH */
3040 for(i=0;i<4;i++)
3041 vrotb(6);
3042 /* stack: ML MH H1 H2 L1 L2 */
3043 tmp = vtop[0];
3044 vtop[0] = vtop[-2];
3045 vtop[-2] = tmp;
3046 /* stack: ML MH H1 L2 H2 L1 */
3047 gen_op('*');
3048 vrotb(3);
3049 vrotb(3);
3050 gen_op('*');
3051 /* stack: ML MH M1 M2 */
3052 gen_op('+');
3053 gen_op('+');
3054 } else if (op == '+' || op == '-') {
3055 /* XXX: add non carry method too (for MIPS or alpha) */
3056 if (op == '+')
3057 op1 = TOK_ADDC1;
3058 else
3059 op1 = TOK_SUBC1;
3060 gen_op(op1);
3061 /* stack: H1 H2 (L1 op L2) */
3062 vrotb(3);
3063 vrotb(3);
3064 gen_op(op1 + 1); /* TOK_xxxC2 */
3065 } else {
3066 gen_op(op);
3067 /* stack: H1 H2 (L1 op L2) */
3068 vrotb(3);
3069 vrotb(3);
3070 /* stack: (L1 op L2) H1 H2 */
3071 gen_op(op);
3072 /* stack: (L1 op L2) (H1 op H2) */
3074 /* stack: L H */
3075 lbuild(t);
3076 break;
3077 case TOK_SAR:
3078 case TOK_SHR:
3079 case TOK_SHL:
3080 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3081 t = vtop[-1].t;
3082 vswap();
3083 lexpand();
3084 vrotb(3);
3085 /* stack: L H shift */
3086 c = (int)vtop->c.i;
3087 /* constant: simpler */
3088 /* NOTE: all comments are for SHL. the other cases are
3089 done by swaping words */
3090 vpop();
3091 if (op != TOK_SHL)
3092 vswap();
3093 if (c >= 32) {
3094 /* stack: L H */
3095 vpop();
3096 if (c > 32) {
3097 vpushi(c - 32);
3098 gen_op(op);
3100 if (op != TOK_SAR) {
3101 vpushi(0);
3102 } else {
3103 gv_dup();
3104 vpushi(31);
3105 gen_op(TOK_SAR);
3107 vswap();
3108 } else {
3109 vswap();
3110 gv_dup();
3111 /* stack: H L L */
3112 vpushi(c);
3113 gen_op(op);
3114 vswap();
3115 vpushi(32 - c);
3116 if (op == TOK_SHL)
3117 gen_op(TOK_SHR);
3118 else
3119 gen_op(TOK_SHL);
3120 vrotb(3);
3121 /* stack: L L H */
3122 vpushi(c);
3123 gen_op(op);
3124 gen_op('|');
3126 if (op != TOK_SHL)
3127 vswap();
3128 lbuild(t);
3129 } else {
3130 /* XXX: should provide a faster fallback on x86 ? */
3131 switch(op) {
3132 case TOK_SAR:
3133 func = __sardi3;
3134 goto gen_func;
3135 case TOK_SHR:
3136 func = __shrdi3;
3137 goto gen_func;
3138 case TOK_SHL:
3139 func = __shldi3;
3140 goto gen_func;
3143 break;
3144 default:
3145 /* compare operations */
3146 t = vtop->t;
3147 vswap();
3148 lexpand();
3149 vrotb(3);
3150 lexpand();
3151 /* stack: L1 H1 L2 H2 */
3152 tmp = vtop[-1];
3153 vtop[-1] = vtop[-2];
3154 vtop[-2] = tmp;
3155 /* stack: L1 L2 H1 H2 */
3156 /* compare high */
3157 op1 = op;
3158 /* when values are equal, we need to compare low words. since
3159 the jump is inverted, we invert the test too. */
3160 if (op1 == TOK_LT)
3161 op1 = TOK_LE;
3162 else if (op1 == TOK_GT)
3163 op1 = TOK_GE;
3164 else if (op1 == TOK_ULT)
3165 op1 = TOK_ULE;
3166 else if (op1 == TOK_UGT)
3167 op1 = TOK_UGE;
3168 a = 0;
3169 b = 0;
3170 gen_op(op1);
3171 if (op1 != TOK_NE) {
3172 a = gtst(1, 0);
3174 if (op != TOK_EQ) {
3175 /* generate non equal test */
3176 /* XXX: NOT PORTABLE yet */
3177 if (a == 0) {
3178 b = gtst(0, 0);
3179 } else {
3180 #ifdef TCC_TARGET_I386
3181 b = psym(0x850f, 0);
3182 #else
3183 error("not implemented");
3184 #endif
3187 /* compare low */
3188 gen_op(op);
3189 a = gtst(1, a);
3190 gsym(b);
3191 vset(VT_INT, VT_JMPI, a);
3192 break;
3196 /* handle integer constant optimizations and various machine
3197 independant opt */
3198 void gen_opic(int op)
3200 int fc, c1, c2, n;
3201 SValue *v1, *v2;
3203 v1 = vtop - 1;
3204 v2 = vtop;
3205 /* currently, we cannot do computations with forward symbols */
3206 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3207 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3208 if (c1 && c2) {
3209 fc = v2->c.i;
3210 switch(op) {
3211 case '+': v1->c.i += fc; break;
3212 case '-': v1->c.i -= fc; break;
3213 case '&': v1->c.i &= fc; break;
3214 case '^': v1->c.i ^= fc; break;
3215 case '|': v1->c.i |= fc; break;
3216 case '*': v1->c.i *= fc; break;
3218 case TOK_PDIV:
3219 case '/':
3220 case '%':
3221 case TOK_UDIV:
3222 case TOK_UMOD:
3223 /* if division by zero, generate explicit division */
3224 if (fc == 0) {
3225 if (const_wanted)
3226 error("division by zero in constant");
3227 goto general_case;
3229 switch(op) {
3230 default: v1->c.i /= fc; break;
3231 case '%': v1->c.i %= fc; break;
3232 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3233 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3235 break;
3236 case TOK_SHL: v1->c.i <<= fc; break;
3237 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3238 case TOK_SAR: v1->c.i >>= fc; break;
3239 /* tests */
3240 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3241 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3242 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3243 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3244 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3245 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3246 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3247 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3248 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3249 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3250 /* logical */
3251 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3252 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3253 default:
3254 goto general_case;
3256 vtop--;
3257 } else {
3258 /* if commutative ops, put c2 as constant */
3259 if (c1 && (op == '+' || op == '&' || op == '^' ||
3260 op == '|' || op == '*')) {
3261 vswap();
3262 swap(&c1, &c2);
3264 fc = vtop->c.i;
3265 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3266 op == TOK_PDIV) &&
3267 fc == 1) ||
3268 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3269 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3270 fc == 0) ||
3271 (op == '&' &&
3272 fc == -1))) {
3273 /* nothing to do */
3274 vtop--;
3275 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3276 /* try to use shifts instead of muls or divs */
3277 if (fc > 0 && (fc & (fc - 1)) == 0) {
3278 n = -1;
3279 while (fc) {
3280 fc >>= 1;
3281 n++;
3283 vtop->c.i = n;
3284 if (op == '*')
3285 op = TOK_SHL;
3286 else if (op == TOK_PDIV)
3287 op = TOK_SAR;
3288 else
3289 op = TOK_SHR;
3291 goto general_case;
3292 } else {
3293 general_case:
3294 /* call low level op generator */
3295 gen_opi(op);
3300 /* generate a floating point operation with constant propagation */
3301 void gen_opif(int op)
3303 int c1, c2;
3304 SValue *v1, *v2;
3305 long double f1, f2;
3307 v1 = vtop - 1;
3308 v2 = vtop;
3309 /* currently, we cannot do computations with forward symbols */
3310 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3311 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3312 if (c1 && c2) {
3313 if (v1->t == VT_FLOAT) {
3314 f1 = v1->c.f;
3315 f2 = v2->c.f;
3316 } else if (v1->t == VT_DOUBLE) {
3317 f1 = v1->c.d;
3318 f2 = v2->c.d;
3319 } else {
3320 f1 = v1->c.ld;
3321 f2 = v2->c.ld;
3324 /* NOTE: we only do constant propagation if finite number (not
3325 NaN or infinity) (ANSI spec) */
3326 if (!ieee_finite(f1) || !ieee_finite(f2))
3327 goto general_case;
3329 switch(op) {
3330 case '+': f1 += f2; break;
3331 case '-': f1 -= f2; break;
3332 case '*': f1 *= f2; break;
3333 case '/':
3334 if (f2 == 0.0) {
3335 if (const_wanted)
3336 error("division by zero in constant");
3337 goto general_case;
3339 f1 /= f2;
3340 break;
3341 /* XXX: also handles tests ? */
3342 default:
3343 goto general_case;
3345 /* XXX: overflow test ? */
3346 if (v1->t == VT_FLOAT) {
3347 v1->c.f = f1;
3348 } else if (v1->t == VT_DOUBLE) {
3349 v1->c.d = f1;
3350 } else {
3351 v1->c.ld = f1;
3353 vtop--;
3354 } else {
3355 general_case:
3356 gen_opf(op);
3361 int pointed_size(int t)
3363 return type_size(pointed_type(t), &t);
3366 #if 0
3367 void check_pointer_types(SValue *p1, SValue *p2)
3369 char buf1[256], buf2[256];
3370 int t1, t2;
3371 t1 = p1->t;
3372 t2 = p2->t;
3373 if (!is_compatible_types(t1, t2)) {
3374 type_to_str(buf1, sizeof(buf1), t1, NULL);
3375 type_to_str(buf2, sizeof(buf2), t2, NULL);
3376 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3379 #endif
3381 /* generic gen_op: handles types problems */
3382 void gen_op(int op)
3384 int u, t1, t2, bt1, bt2, t;
3386 t1 = vtop[-1].t;
3387 t2 = vtop[0].t;
3388 bt1 = t1 & VT_BTYPE;
3389 bt2 = t2 & VT_BTYPE;
3391 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3392 /* at least one operand is a pointer */
3393 /* relationnal op: must be both pointers */
3394 if (op >= TOK_ULT && op <= TOK_GT) {
3395 // check_pointer_types(vtop, vtop - 1);
3396 /* pointers are handled are unsigned */
3397 t = VT_INT | VT_UNSIGNED;
3398 goto std_op;
3400 /* if both pointers, then it must be the '-' op */
3401 if ((t1 & VT_BTYPE) == VT_PTR &&
3402 (t2 & VT_BTYPE) == VT_PTR) {
3403 if (op != '-')
3404 error("cannot use pointers here");
3405 // check_pointer_types(vtop - 1, vtop);
3406 /* XXX: check that types are compatible */
3407 u = pointed_size(t1);
3408 gen_opic(op);
3409 /* set to integer type */
3410 vtop->t = VT_INT;
3411 vpushi(u);
3412 gen_op(TOK_PDIV);
3413 } else {
3414 /* exactly one pointer : must be '+' or '-'. */
3415 if (op != '-' && op != '+')
3416 error("cannot use pointers here");
3417 /* Put pointer as first operand */
3418 if ((t2 & VT_BTYPE) == VT_PTR) {
3419 vswap();
3420 swap(&t1, &t2);
3422 /* XXX: cast to int ? (long long case) */
3423 vpushi(pointed_size(vtop[-1].t));
3424 gen_op('*');
3425 #ifdef CONFIG_TCC_BCHECK
3426 /* if evaluating constant expression, no code should be
3427 generated, so no bound check */
3428 if (do_bounds_check && !const_wanted) {
3429 /* if bounded pointers, we generate a special code to
3430 test bounds */
3431 if (op == '-') {
3432 vpushi(0);
3433 vswap();
3434 gen_op('-');
3436 gen_bounded_ptr_add();
3437 } else
3438 #endif
3440 gen_opic(op);
3442 /* put again type if gen_opic() swaped operands */
3443 vtop->t = t1;
3445 } else if (is_float(bt1) || is_float(bt2)) {
3446 /* compute bigger type and do implicit casts */
3447 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3448 t = VT_LDOUBLE;
3449 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3450 t = VT_DOUBLE;
3451 } else {
3452 t = VT_FLOAT;
3454 /* floats can only be used for a few operations */
3455 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3456 (op < TOK_ULT || op > TOK_GT))
3457 error("invalid operands for binary operation");
3458 goto std_op;
3459 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3460 /* cast to biggest op */
3461 t = VT_LLONG;
3462 /* convert to unsigned if it does not fit in a long long */
3463 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3464 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3465 t |= VT_UNSIGNED;
3466 goto std_op;
3467 } else {
3468 /* integer operations */
3469 t = VT_INT;
3470 /* convert to unsigned if it does not fit in an integer */
3471 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3472 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3473 t |= VT_UNSIGNED;
3474 std_op:
3475 /* XXX: currently, some unsigned operations are explicit, so
3476 we modify them here */
3477 if (t & VT_UNSIGNED) {
3478 if (op == TOK_SAR)
3479 op = TOK_SHR;
3480 else if (op == '/')
3481 op = TOK_UDIV;
3482 else if (op == '%')
3483 op = TOK_UMOD;
3484 else if (op == TOK_LT)
3485 op = TOK_ULT;
3486 else if (op == TOK_GT)
3487 op = TOK_UGT;
3488 else if (op == TOK_LE)
3489 op = TOK_ULE;
3490 else if (op == TOK_GE)
3491 op = TOK_UGE;
3493 vswap();
3494 gen_cast(t);
3495 vswap();
3496 /* special case for shifts and long long: we keep the shift as
3497 an integer */
3498 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3499 gen_cast(VT_INT);
3500 else
3501 gen_cast(t);
3502 if (is_float(t))
3503 gen_opif(op);
3504 else if ((t & VT_BTYPE) == VT_LLONG)
3505 gen_opl(op);
3506 else
3507 gen_opic(op);
3508 if (op >= TOK_ULT && op <= TOK_GT) {
3509 /* relationnal op: the result is an int */
3510 vtop->t = VT_INT;
3511 } else {
3512 vtop->t = t;
3517 /* generic itof for unsigned long long case */
3518 void gen_cvt_itof1(int t)
3520 GFuncContext gf;
3522 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3523 (VT_LLONG | VT_UNSIGNED)) {
3525 gfunc_start(&gf, FUNC_CDECL);
3526 gfunc_param(&gf);
3527 if (t == VT_FLOAT)
3528 vpushi((int)&__ulltof);
3529 else if (t == VT_DOUBLE)
3530 vpushi((int)&__ulltod);
3531 else
3532 vpushi((int)&__ulltold);
3533 gfunc_call(&gf);
3534 vpushi(0);
3535 vtop->r = REG_FRET;
3536 } else {
3537 gen_cvt_itof(t);
3541 /* generic ftoi for unsigned long long case */
3542 void gen_cvt_ftoi1(int t)
3544 GFuncContext gf;
3545 int st;
3547 if (t == (VT_LLONG | VT_UNSIGNED)) {
3548 /* not handled natively */
3549 gfunc_start(&gf, FUNC_CDECL);
3550 st = vtop->t & VT_BTYPE;
3551 gfunc_param(&gf);
3552 if (st == VT_FLOAT)
3553 vpushi((int)&__ftoull);
3554 else if (st == VT_DOUBLE)
3555 vpushi((int)&__dtoull);
3556 else
3557 vpushi((int)&__ldtoull);
3558 gfunc_call(&gf);
3559 vpushi(0);
3560 vtop->r = REG_IRET;
3561 vtop->r2 = REG_LRET;
3562 } else {
3563 gen_cvt_ftoi(t);
3567 /* force char or short cast */
3568 void force_charshort_cast(int t)
3570 int bits, dbt;
3571 dbt = t & VT_BTYPE;
3572 /* XXX: add optimization if lvalue : just change type and offset */
3573 if (dbt == VT_BYTE)
3574 bits = 8;
3575 else
3576 bits = 16;
3577 if (t & VT_UNSIGNED) {
3578 vpushi((1 << bits) - 1);
3579 gen_op('&');
3580 } else {
3581 bits = 32 - bits;
3582 vpushi(bits);
3583 gen_op(TOK_SHL);
3584 vpushi(bits);
3585 gen_op(TOK_SAR);
3589 /* cast 'vtop' to 't' type */
3590 void gen_cast(int t)
3592 int sbt, dbt, sf, df, c;
3594 /* special delayed cast for char/short */
3595 /* XXX: in some cases (multiple cascaded casts), it may still
3596 be incorrect */
3597 if (vtop->r & VT_MUSTCAST) {
3598 vtop->r &= ~VT_MUSTCAST;
3599 force_charshort_cast(vtop->t);
3602 dbt = t & (VT_BTYPE | VT_UNSIGNED);
3603 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
3605 if (sbt != dbt) {
3606 sf = is_float(sbt);
3607 df = is_float(dbt);
3608 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3609 if (sf && df) {
3610 /* convert from fp to fp */
3611 if (c) {
3612 /* constant case: we can do it now */
3613 /* XXX: in ISOC, cannot do it if error in convert */
3614 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
3615 vtop->c.f = (float)vtop->c.d;
3616 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
3617 vtop->c.f = (float)vtop->c.ld;
3618 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
3619 vtop->c.d = (double)vtop->c.f;
3620 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
3621 vtop->c.d = (double)vtop->c.ld;
3622 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
3623 vtop->c.ld = (long double)vtop->c.f;
3624 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
3625 vtop->c.ld = (long double)vtop->c.d;
3626 } else {
3627 /* non constant case: generate code */
3628 gen_cvt_ftof(dbt);
3630 } else if (df) {
3631 /* convert int to fp */
3632 if (c) {
3633 switch(sbt) {
3634 case VT_LLONG | VT_UNSIGNED:
3635 case VT_LLONG:
3636 /* XXX: add const cases for long long */
3637 goto do_itof;
3638 case VT_INT | VT_UNSIGNED:
3639 switch(dbt) {
3640 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
3641 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
3642 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
3644 break;
3645 default:
3646 switch(dbt) {
3647 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
3648 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
3649 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
3651 break;
3653 } else {
3654 do_itof:
3655 gen_cvt_itof1(dbt);
3657 } else if (sf) {
3658 /* convert fp to int */
3659 /* we handle char/short/etc... with generic code */
3660 if (dbt != (VT_INT | VT_UNSIGNED) &&
3661 dbt != (VT_LLONG | VT_UNSIGNED) &&
3662 dbt != VT_LLONG)
3663 dbt = VT_INT;
3664 if (c) {
3665 switch(dbt) {
3666 case VT_LLONG | VT_UNSIGNED:
3667 case VT_LLONG:
3668 /* XXX: add const cases for long long */
3669 goto do_ftoi;
3670 case VT_INT | VT_UNSIGNED:
3671 switch(sbt) {
3672 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
3673 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3674 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3676 break;
3677 default:
3678 /* int case */
3679 switch(sbt) {
3680 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
3681 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
3682 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
3684 break;
3686 } else {
3687 do_ftoi:
3688 gen_cvt_ftoi1(dbt);
3690 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
3691 /* additionnal cast for char/short/bool... */
3692 vtop->t = dbt;
3693 gen_cast(t);
3695 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
3696 if ((sbt & VT_BTYPE) != VT_LLONG) {
3697 /* scalar to long long */
3698 if (c) {
3699 if (sbt == (VT_INT | VT_UNSIGNED))
3700 vtop->c.ll = vtop->c.ui;
3701 else
3702 vtop->c.ll = vtop->c.i;
3703 } else {
3704 /* machine independant conversion */
3705 gv(RC_INT);
3706 /* generate high word */
3707 if (sbt == (VT_INT | VT_UNSIGNED)) {
3708 vpushi(0);
3709 gv(RC_INT);
3710 } else {
3711 gv_dup();
3712 vpushi(31);
3713 gen_op(TOK_SAR);
3715 /* patch second register */
3716 vtop[-1].r2 = vtop->r;
3717 vpop();
3720 } else if (dbt == VT_BOOL) {
3721 /* scalar to bool */
3722 vpushi(0);
3723 gen_op(TOK_NE);
3724 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
3725 (dbt & VT_BTYPE) == VT_SHORT) {
3726 force_charshort_cast(t);
3727 } else if ((dbt & VT_BTYPE) == VT_INT) {
3728 /* scalar to int */
3729 if (sbt == VT_LLONG) {
3730 /* from long long: just take low order word */
3731 lexpand();
3732 vpop();
3734 /* if lvalue and single word type, nothing to do because
3735 the lvalue already contains the real type size (see
3736 VT_LVAL_xxx constants) */
3739 vtop->t = t;
3742 /* return type size. Put alignment at 'a' */
3743 int type_size(int t, int *a)
3745 Sym *s;
3746 int bt;
3748 bt = t & VT_BTYPE;
3749 if (bt == VT_STRUCT) {
3750 /* struct/union */
3751 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3752 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
3753 return s->c;
3754 } else if (bt == VT_PTR) {
3755 if (t & VT_ARRAY) {
3756 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3757 return type_size(s->t, a) * s->c;
3758 } else {
3759 *a = PTR_SIZE;
3760 return PTR_SIZE;
3762 } else if (bt == VT_LDOUBLE) {
3763 *a = LDOUBLE_ALIGN;
3764 return LDOUBLE_SIZE;
3765 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3766 *a = 8;
3767 return 8;
3768 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
3769 *a = 4;
3770 return 4;
3771 } else if (bt == VT_SHORT) {
3772 *a = 2;
3773 return 2;
3774 } else {
3775 /* char, void, function, _Bool */
3776 *a = 1;
3777 return 1;
3781 /* return the pointed type of t */
3782 int pointed_type(int t)
3784 Sym *s;
3785 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3786 return s->t | (t & ~VT_TYPE);
3789 int mk_pointer(int t)
3791 int p;
3792 p = anon_sym++;
3793 sym_push(p, t, 0, -1);
3794 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
3797 int is_compatible_types(int t1, int t2)
3799 Sym *s1, *s2;
3800 int bt1, bt2;
3802 t1 &= VT_TYPE;
3803 t2 &= VT_TYPE;
3804 bt1 = t1 & VT_BTYPE;
3805 bt2 = t2 & VT_BTYPE;
3806 if (bt1 == VT_PTR) {
3807 t1 = pointed_type(t1);
3808 /* if function, then convert implicitely to function pointer */
3809 if (bt2 != VT_FUNC) {
3810 if (bt2 != VT_PTR)
3811 return 0;
3812 t2 = pointed_type(t2);
3814 /* void matches everything */
3815 t1 &= VT_TYPE;
3816 t2 &= VT_TYPE;
3817 if (t1 == VT_VOID || t2 == VT_VOID)
3818 return 1;
3819 return is_compatible_types(t1, t2);
3820 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3821 return (t2 == t1);
3822 } else if (bt1 == VT_FUNC) {
3823 if (bt2 != VT_FUNC)
3824 return 0;
3825 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
3826 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
3827 if (!is_compatible_types(s1->t, s2->t))
3828 return 0;
3829 /* XXX: not complete */
3830 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
3831 return 1;
3832 if (s1->c != s2->c)
3833 return 0;
3834 while (s1 != NULL) {
3835 if (s2 == NULL)
3836 return 0;
3837 if (!is_compatible_types(s1->t, s2->t))
3838 return 0;
3839 s1 = s1->next;
3840 s2 = s2->next;
3842 if (s2)
3843 return 0;
3844 return 1;
3845 } else {
3846 /* XXX: not complete */
3847 return 1;
3851 /* print a type. If 'varstr' is not NULL, then the variable is also
3852 printed in the type */
3853 /* XXX: union */
3854 /* XXX: add array and function pointers */
3855 void type_to_str(char *buf, int buf_size,
3856 int t, const char *varstr)
3858 int bt, v;
3859 Sym *s, *sa;
3860 char buf1[256];
3861 const char *tstr;
3863 t = t & VT_TYPE;
3864 bt = t & VT_BTYPE;
3865 buf[0] = '\0';
3866 if (t & VT_UNSIGNED)
3867 pstrcat(buf, buf_size, "unsigned ");
3868 switch(bt) {
3869 case VT_VOID:
3870 tstr = "void";
3871 goto add_tstr;
3872 case VT_BOOL:
3873 tstr = "_Bool";
3874 goto add_tstr;
3875 case VT_BYTE:
3876 tstr = "char";
3877 goto add_tstr;
3878 case VT_SHORT:
3879 tstr = "short";
3880 goto add_tstr;
3881 case VT_INT:
3882 tstr = "int";
3883 goto add_tstr;
3884 case VT_LONG:
3885 tstr = "long";
3886 goto add_tstr;
3887 case VT_LLONG:
3888 tstr = "long long";
3889 goto add_tstr;
3890 case VT_FLOAT:
3891 tstr = "float";
3892 goto add_tstr;
3893 case VT_DOUBLE:
3894 tstr = "double";
3895 goto add_tstr;
3896 case VT_LDOUBLE:
3897 tstr = "long double";
3898 add_tstr:
3899 pstrcat(buf, buf_size, tstr);
3900 break;
3901 case VT_ENUM:
3902 case VT_STRUCT:
3903 if (bt == VT_STRUCT)
3904 tstr = "struct ";
3905 else
3906 tstr = "enum ";
3907 pstrcat(buf, buf_size, tstr);
3908 v = (unsigned)t >> VT_STRUCT_SHIFT;
3909 if (v >= SYM_FIRST_ANOM)
3910 pstrcat(buf, buf_size, "<anonymous>");
3911 else
3912 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3913 break;
3914 case VT_FUNC:
3915 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3916 type_to_str(buf, buf_size, s->t, varstr);
3917 pstrcat(buf, buf_size, "(");
3918 sa = s->next;
3919 while (sa != NULL) {
3920 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
3921 pstrcat(buf, buf_size, buf1);
3922 sa = sa->next;
3923 if (sa)
3924 pstrcat(buf, buf_size, ", ");
3926 pstrcat(buf, buf_size, ")");
3927 goto no_var;
3928 case VT_PTR:
3929 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3930 pstrcpy(buf1, sizeof(buf1), "*");
3931 if (varstr)
3932 pstrcat(buf1, sizeof(buf1), varstr);
3933 type_to_str(buf, buf_size, s->t, buf1);
3934 goto no_var;
3936 if (varstr) {
3937 pstrcat(buf, buf_size, " ");
3938 pstrcat(buf, buf_size, varstr);
3940 no_var: ;
3943 /* verify type compatibility to store vtop in 'dt' type, and generate
3944 casts if needed. */
3945 void gen_assign_cast(int dt)
3947 int st;
3948 char buf1[256], buf2[256];
3950 st = vtop->t; /* source type */
3951 if ((dt & VT_BTYPE) == VT_PTR) {
3952 /* special cases for pointers */
3953 /* a function is implicitely a function pointer */
3954 if ((st & VT_BTYPE) == VT_FUNC) {
3955 if (!is_compatible_types(pointed_type(dt), st))
3956 goto error;
3957 else
3958 goto type_ok;
3960 /* '0' can also be a pointer */
3961 if ((st & VT_BTYPE) == VT_INT &&
3962 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
3963 vtop->c.i == 0)
3964 goto type_ok;
3966 if (!is_compatible_types(dt, st)) {
3967 error:
3968 type_to_str(buf1, sizeof(buf1), st, NULL);
3969 type_to_str(buf2, sizeof(buf2), dt, NULL);
3970 error("cannot cast '%s' to '%s'", buf1, buf2);
3972 type_ok:
3973 gen_cast(dt);
3976 /* store vtop in lvalue pushed on stack */
3977 void vstore(void)
3979 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
3980 GFuncContext gf;
3982 ft = vtop[-1].t;
3983 sbt = vtop->t & VT_BTYPE;
3984 dbt = ft & VT_BTYPE;
3985 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
3986 (sbt == VT_INT && dbt == VT_SHORT)) {
3987 /* optimize char/short casts */
3988 delayed_cast = VT_MUSTCAST;
3989 vtop->t = ft & VT_TYPE;
3990 } else {
3991 delayed_cast = 0;
3992 gen_assign_cast(ft & VT_TYPE);
3995 if (sbt == VT_STRUCT) {
3996 /* if structure, only generate pointer */
3997 /* structure assignment : generate memcpy */
3998 /* XXX: optimize if small size */
3999 vdup();
4000 gfunc_start(&gf, FUNC_CDECL);
4001 /* type size */
4002 size = type_size(vtop->t, &align);
4003 vpushi(size);
4004 gfunc_param(&gf);
4005 /* source */
4006 vtop->t = VT_INT;
4007 gaddrof();
4008 gfunc_param(&gf);
4009 /* destination */
4010 vswap();
4011 vtop->t = VT_INT;
4012 gaddrof();
4013 gfunc_param(&gf);
4015 save_regs(0);
4016 vpushi((int)&memcpy);
4017 gfunc_call(&gf);
4018 /* leave source on stack */
4019 } else if (ft & VT_BITFIELD) {
4020 /* bitfield store handling */
4021 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4022 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4023 /* remove bit field info to avoid loops */
4024 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4026 /* duplicate destination */
4027 vdup();
4028 vtop[-1] = vtop[-2];
4030 /* mask and shift source */
4031 vpushi((1 << bit_size) - 1);
4032 gen_op('&');
4033 vpushi(bit_pos);
4034 gen_op(TOK_SHL);
4035 /* load destination, mask and or with source */
4036 vswap();
4037 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4038 gen_op('&');
4039 gen_op('|');
4040 /* store result */
4041 vstore();
4042 } else {
4043 #ifdef CONFIG_TCC_BCHECK
4044 /* bound check case */
4045 if (vtop[-1].r & VT_MUSTBOUND) {
4046 vswap();
4047 gbound();
4048 vswap();
4050 #endif
4051 rc = RC_INT;
4052 if (is_float(ft))
4053 rc = RC_FLOAT;
4054 r = gv(rc); /* generate value */
4055 /* if lvalue was saved on stack, must read it */
4056 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4057 SValue sv;
4058 t = get_reg(RC_INT);
4059 sv.t = VT_INT;
4060 sv.r = VT_LOCAL | VT_LVAL;
4061 sv.c.ul = vtop[-1].c.ul;
4062 load(t, &sv);
4063 vtop[-1].r = t | VT_LVAL;
4065 store(r, vtop - 1);
4066 /* two word case handling : store second register at word + 4 */
4067 if ((ft & VT_BTYPE) == VT_LLONG) {
4068 vswap();
4069 /* convert to int to increment easily */
4070 vtop->t = VT_INT;
4071 gaddrof();
4072 vpushi(4);
4073 gen_op('+');
4074 vtop->r |= VT_LVAL;
4075 vswap();
4076 /* XXX: it works because r2 is spilled last ! */
4077 store(vtop->r2, vtop - 1);
4079 vswap();
4080 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4081 vtop->r |= delayed_cast;
4085 /* post defines POST/PRE add. c is the token ++ or -- */
4086 void inc(int post, int c)
4088 test_lvalue();
4089 vdup(); /* save lvalue */
4090 if (post) {
4091 gv_dup(); /* duplicate value */
4092 vrotb(3);
4093 vrotb(3);
4095 /* add constant */
4096 vpushi(c - TOK_MID);
4097 gen_op('+');
4098 vstore(); /* store value */
4099 if (post)
4100 vpop(); /* if post op, return saved value */
4103 /* Parse GNUC __attribute__ extension. Currently, the following
4104 extensions are recognized:
4105 - aligned(n) : set data/function alignment.
4106 - section(x) : generate data/code in this section.
4107 - unused : currently ignored, but may be used someday.
4109 void parse_attribute(AttributeDef *ad)
4111 int t, n;
4113 next();
4114 skip('(');
4115 skip('(');
4116 while (tok != ')') {
4117 if (tok < TOK_IDENT)
4118 expect("attribute name");
4119 t = tok;
4120 next();
4121 switch(t) {
4122 case TOK_SECTION:
4123 case TOK___SECTION__:
4124 skip('(');
4125 if (tok != TOK_STR)
4126 expect("section name");
4127 ad->section = find_section(tokc.ts->str);
4128 next();
4129 skip(')');
4130 break;
4131 case TOK_ALIGNED:
4132 case TOK___ALIGNED__:
4133 skip('(');
4134 n = expr_const();
4135 if (n <= 0 || (n & (n - 1)) != 0)
4136 error("alignment must be a positive power of two");
4137 ad->aligned = n;
4138 skip(')');
4139 break;
4140 case TOK_UNUSED:
4141 case TOK___UNUSED__:
4142 /* currently, no need to handle it because tcc does not
4143 track unused objects */
4144 break;
4145 case TOK_NORETURN:
4146 case TOK___NORETURN__:
4147 /* currently, no need to handle it because tcc does not
4148 track unused objects */
4149 break;
4150 case TOK_CDECL:
4151 case TOK___CDECL:
4152 case TOK___CDECL__:
4153 ad->func_call = FUNC_CDECL;
4154 break;
4155 case TOK_STDCALL:
4156 case TOK___STDCALL:
4157 case TOK___STDCALL__:
4158 ad->func_call = FUNC_STDCALL;
4159 break;
4160 default:
4161 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4162 /* skip parameters */
4163 /* XXX: skip parenthesis too */
4164 if (tok == '(') {
4165 next();
4166 while (tok != ')' && tok != -1)
4167 next();
4168 next();
4170 break;
4172 if (tok != ',')
4173 break;
4174 next();
4176 skip(')');
4177 skip(')');
4180 /* enum/struct/union declaration */
4181 int struct_decl(int u)
4183 int a, t, b, v, size, align, maxalign, c, offset;
4184 int bit_size, bit_pos, bsize, bt, lbit_pos;
4185 Sym *s, *ss, **ps;
4186 AttributeDef ad;
4188 a = tok; /* save decl type */
4189 next();
4190 if (tok != '{') {
4191 v = tok;
4192 next();
4193 /* struct already defined ? return it */
4194 /* XXX: check consistency */
4195 s = sym_find(v | SYM_STRUCT);
4196 if (s) {
4197 if (s->t != a)
4198 error("invalid type");
4199 goto do_decl;
4201 } else {
4202 v = anon_sym++;
4204 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4205 /* put struct/union/enum name in type */
4206 do_decl:
4207 u = u | (v << VT_STRUCT_SHIFT);
4209 if (tok == '{') {
4210 next();
4211 if (s->c)
4212 error("struct/union/enum already defined");
4213 /* cannot be empty */
4214 c = 0;
4215 maxalign = 0;
4216 ps = &s->next;
4217 bit_pos = 0;
4218 offset = 0;
4219 while (1) {
4220 if (a == TOK_ENUM) {
4221 v = tok;
4222 next();
4223 if (tok == '=') {
4224 next();
4225 c = expr_const();
4227 /* enum symbols have static storage */
4228 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4229 if (tok == ',')
4230 next();
4231 c++;
4232 } else {
4233 parse_btype(&b, &ad);
4234 while (1) {
4235 bit_size = -1;
4236 v = 0;
4237 if (tok != ':') {
4238 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4239 if ((t & VT_BTYPE) == VT_FUNC ||
4240 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4241 error("invalid type for '%s'",
4242 get_tok_str(v, NULL));
4243 } else {
4244 t = b;
4246 if (tok == ':') {
4247 next();
4248 bit_size = expr_const();
4249 /* XXX: handle v = 0 case for messages */
4250 if (bit_size < 0)
4251 error("negative width in bit-field '%s'",
4252 get_tok_str(v, NULL));
4253 if (v && bit_size == 0)
4254 error("zero width for bit-field '%s'",
4255 get_tok_str(v, NULL));
4257 size = type_size(t, &align);
4258 lbit_pos = 0;
4259 if (bit_size >= 0) {
4260 bt = t & VT_BTYPE;
4261 if (bt != VT_INT &&
4262 bt != VT_BYTE &&
4263 bt != VT_SHORT)
4264 error("bitfields must have scalar type");
4265 bsize = size * 8;
4266 if (bit_size > bsize) {
4267 error("width of '%s' exceeds its type",
4268 get_tok_str(v, NULL));
4269 } else if (bit_size == bsize) {
4270 /* no need for bit fields */
4271 bit_pos = 0;
4272 } else if (bit_size == 0) {
4273 /* XXX: what to do if only padding in a
4274 structure ? */
4275 /* zero size: means to pad */
4276 if (bit_pos > 0)
4277 bit_pos = bsize;
4278 } else {
4279 /* we do not have enough room ? */
4280 if ((bit_pos + bit_size) > bsize)
4281 bit_pos = 0;
4282 lbit_pos = bit_pos;
4283 /* XXX: handle LSB first */
4284 t |= VT_BITFIELD |
4285 (bit_pos << VT_STRUCT_SHIFT) |
4286 (bit_size << (VT_STRUCT_SHIFT + 6));
4287 bit_pos += bit_size;
4289 } else {
4290 bit_pos = 0;
4292 if (v) {
4293 /* add new memory data only if starting
4294 bit field */
4295 if (lbit_pos == 0) {
4296 if (a == TOK_STRUCT) {
4297 c = (c + align - 1) & -align;
4298 offset = c;
4299 c += size;
4300 } else {
4301 offset = 0;
4302 if (size > c)
4303 c = size;
4305 if (align > maxalign)
4306 maxalign = align;
4308 #if 0
4309 printf("add field %s offset=%d",
4310 get_tok_str(v, NULL), offset);
4311 if (t & VT_BITFIELD) {
4312 printf(" pos=%d size=%d",
4313 (t >> VT_STRUCT_SHIFT) & 0x3f,
4314 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4316 printf("\n");
4317 #endif
4318 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4319 *ps = ss;
4320 ps = &ss->next;
4322 if (tok == ';' || tok == -1)
4323 break;
4324 skip(',');
4326 skip(';');
4328 if (tok == '}')
4329 break;
4331 skip('}');
4332 /* size for struct/union, dummy for enum */
4333 s->c = (c + maxalign - 1) & -maxalign;
4335 return u;
4338 /* return 0 if no type declaration. otherwise, return the basic type
4339 and skip it.
4341 int parse_btype(int *type_ptr, AttributeDef *ad)
4343 int t, u, type_found;
4344 Sym *s;
4346 memset(ad, 0, sizeof(AttributeDef));
4347 type_found = 0;
4348 t = 0;
4349 while(1) {
4350 switch(tok) {
4351 /* basic types */
4352 case TOK_CHAR:
4353 u = VT_BYTE;
4354 basic_type:
4355 next();
4356 basic_type1:
4357 if ((t & VT_BTYPE) != 0)
4358 error("too many basic types");
4359 t |= u;
4360 break;
4361 case TOK_VOID:
4362 u = VT_VOID;
4363 goto basic_type;
4364 case TOK_SHORT:
4365 u = VT_SHORT;
4366 goto basic_type;
4367 case TOK_INT:
4368 next();
4369 break;
4370 case TOK_LONG:
4371 next();
4372 if ((t & VT_BTYPE) == VT_DOUBLE) {
4373 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4374 } else if ((t & VT_BTYPE) == VT_LONG) {
4375 t = (t & ~VT_BTYPE) | VT_LLONG;
4376 } else {
4377 u = VT_LONG;
4378 goto basic_type1;
4380 break;
4381 case TOK_BOOL:
4382 u = VT_BOOL;
4383 goto basic_type;
4384 case TOK_FLOAT:
4385 u = VT_FLOAT;
4386 goto basic_type;
4387 case TOK_DOUBLE:
4388 next();
4389 if ((t & VT_BTYPE) == VT_LONG) {
4390 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4391 } else {
4392 u = VT_DOUBLE;
4393 goto basic_type1;
4395 break;
4396 case TOK_ENUM:
4397 u = struct_decl(VT_ENUM);
4398 goto basic_type1;
4399 case TOK_STRUCT:
4400 case TOK_UNION:
4401 u = struct_decl(VT_STRUCT);
4402 goto basic_type1;
4404 /* type modifiers */
4405 case TOK_CONST:
4406 case TOK_VOLATILE:
4407 case TOK_REGISTER:
4408 case TOK_SIGNED:
4409 case TOK___SIGNED__:
4410 case TOK_AUTO:
4411 case TOK_INLINE:
4412 case TOK___INLINE__:
4413 case TOK_RESTRICT:
4414 next();
4415 break;
4416 case TOK_UNSIGNED:
4417 t |= VT_UNSIGNED;
4418 next();
4419 break;
4421 /* storage */
4422 case TOK_EXTERN:
4423 t |= VT_EXTERN;
4424 next();
4425 break;
4426 case TOK_STATIC:
4427 t |= VT_STATIC;
4428 next();
4429 break;
4430 case TOK_TYPEDEF:
4431 t |= VT_TYPEDEF;
4432 next();
4433 break;
4434 /* GNUC attribute */
4435 case TOK___ATTRIBUTE__:
4436 parse_attribute(ad);
4437 break;
4438 default:
4439 s = sym_find(tok);
4440 if (!s || !(s->t & VT_TYPEDEF))
4441 goto the_end;
4442 t |= (s->t & ~VT_TYPEDEF);
4443 next();
4444 break;
4446 type_found = 1;
4448 the_end:
4449 /* long is never used as type */
4450 if ((t & VT_BTYPE) == VT_LONG)
4451 t = (t & ~VT_BTYPE) | VT_INT;
4452 *type_ptr = t;
4453 return type_found;
4456 int post_type(int t, AttributeDef *ad)
4458 int p, n, pt, l, t1;
4459 Sym **plast, *s, *first;
4460 AttributeDef ad1;
4462 if (tok == '(') {
4463 /* function declaration */
4464 next();
4465 l = 0;
4466 first = NULL;
4467 plast = &first;
4468 while (tok != ')') {
4469 /* read param name and compute offset */
4470 if (l != FUNC_OLD) {
4471 if (!parse_btype(&pt, &ad1)) {
4472 if (l) {
4473 error("invalid type");
4474 } else {
4475 l = FUNC_OLD;
4476 goto old_proto;
4479 l = FUNC_NEW;
4480 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4481 break;
4482 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4483 if ((pt & VT_BTYPE) == VT_VOID)
4484 error("parameter declared as void");
4485 } else {
4486 old_proto:
4487 n = tok;
4488 pt = VT_INT;
4489 next();
4491 /* array must be transformed to pointer according to ANSI C */
4492 pt &= ~VT_ARRAY;
4493 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4494 *plast = s;
4495 plast = &s->next;
4496 if (tok == ',') {
4497 next();
4498 if (l == FUNC_NEW && tok == TOK_DOTS) {
4499 l = FUNC_ELLIPSIS;
4500 next();
4501 break;
4505 /* if no parameters, then old type prototype */
4506 if (l == 0)
4507 l = FUNC_OLD;
4508 skip(')');
4509 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4510 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4511 /* we push a anonymous symbol which will contain the function prototype */
4512 p = anon_sym++;
4513 s = sym_push(p, t, ad->func_call, l);
4514 s->next = first;
4515 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4516 } else if (tok == '[') {
4517 /* array definition */
4518 next();
4519 n = -1;
4520 if (tok != ']') {
4521 n = expr_const();
4522 if (n < 0)
4523 error("invalid array size");
4525 skip(']');
4526 /* parse next post type */
4527 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4528 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4530 /* we push a anonymous symbol which will contain the array
4531 element type */
4532 p = anon_sym++;
4533 sym_push(p, t, 0, n);
4534 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4536 return t;
4539 /* Read a type declaration (except basic type), and return the
4540 type. 'td' is a bitmask indicating which kind of type decl is
4541 expected. 't' should contain the basic type. 'ad' is the attribute
4542 definition of the basic type. It can be modified by type_decl(). */
4543 int type_decl(AttributeDef *ad, int *v, int t, int td)
4545 int u, p;
4546 Sym *s;
4548 while (tok == '*') {
4549 next();
4550 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4551 next();
4552 t = mk_pointer(t);
4555 /* recursive type */
4556 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4557 if (tok == '(') {
4558 next();
4559 /* XXX: this is not correct to modify 'ad' at this point, but
4560 the syntax is not clear */
4561 if (tok == TOK___ATTRIBUTE__)
4562 parse_attribute(ad);
4563 u = type_decl(ad, v, 0, td);
4564 skip(')');
4565 } else {
4566 u = 0;
4567 /* type identifier */
4568 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4569 *v = tok;
4570 next();
4571 } else {
4572 if (!(td & TYPE_ABSTRACT))
4573 expect("identifier");
4574 *v = 0;
4577 /* append t at the end of u */
4578 t = post_type(t, ad);
4579 if (tok == TOK___ATTRIBUTE__)
4580 parse_attribute(ad);
4581 if (!u)
4582 return t;
4583 p = u;
4584 while(1) {
4585 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4586 p = s->t;
4587 if (!p) {
4588 s->t = t;
4589 break;
4592 return u;
4595 /* define a new external reference to a symbol 'v' of type 'u' */
4596 Sym *external_sym(int v, int u, int r)
4598 Sym *s;
4600 s = sym_find(v);
4601 if (!s) {
4602 /* push forward reference */
4603 s = sym_push1(&global_stack,
4604 v, u | VT_EXTERN, 0);
4605 s->r = r | VT_CONST | VT_SYM;
4607 return s;
4610 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4611 static int lvalue_type(int t)
4613 int bt, r;
4614 r = VT_LVAL;
4615 bt = t & VT_BTYPE;
4616 if (bt == VT_BYTE)
4617 r |= VT_LVAL_BYTE;
4618 else if (bt == VT_SHORT)
4619 r |= VT_LVAL_SHORT;
4620 else
4621 return r;
4622 if (t & VT_UNSIGNED)
4623 r |= VT_LVAL_UNSIGNED;
4624 return r;
4627 /* indirection with full error checking and bound check */
4628 static void indir(void)
4630 if ((vtop->t & VT_BTYPE) != VT_PTR)
4631 expect("pointer");
4632 if (vtop->r & VT_LVAL)
4633 gv(RC_INT);
4634 vtop->t = pointed_type(vtop->t);
4635 /* an array is never an lvalue */
4636 if (!(vtop->t & VT_ARRAY)) {
4637 vtop->r |= lvalue_type(vtop->t);
4638 /* if bound checking, the referenced pointer must be checked */
4639 if (do_bounds_check)
4640 vtop->r |= VT_MUSTBOUND;
4644 /* pass a parameter to a function and do type checking and casting */
4645 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
4647 int func_type;
4648 func_type = func->c;
4649 if (func_type == FUNC_OLD ||
4650 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
4651 /* default casting : only need to convert float to double */
4652 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
4653 gen_cast(VT_DOUBLE);
4654 } else if (arg == NULL) {
4655 error("too many arguments to function");
4656 } else {
4657 gen_assign_cast(arg->t);
4659 gfunc_param(gf);
4662 void unary(void)
4664 int n, t, ft, fc, p, align, size, r, data_offset;
4665 Sym *s;
4666 GFuncContext gf;
4667 AttributeDef ad;
4669 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
4670 vpushi(tokc.i);
4671 next();
4672 } else if (tok == TOK_CUINT) {
4673 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
4674 next();
4675 } else if (tok == TOK_CLLONG) {
4676 vsetc(VT_LLONG, VT_CONST, &tokc);
4677 next();
4678 } else if (tok == TOK_CULLONG) {
4679 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
4680 next();
4681 } else if (tok == TOK_CFLOAT) {
4682 vsetc(VT_FLOAT, VT_CONST, &tokc);
4683 next();
4684 } else if (tok == TOK_CDOUBLE) {
4685 vsetc(VT_DOUBLE, VT_CONST, &tokc);
4686 next();
4687 } else if (tok == TOK_CLDOUBLE) {
4688 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
4689 next();
4690 } else if (tok == TOK___FUNC__) {
4691 /* special function name identifier */
4692 /* generate (char *) type */
4693 data_offset = data_section->data_ptr - data_section->data;
4694 vpush_ref(mk_pointer(VT_BYTE), data_section, data_offset);
4695 strcpy(data_section->data + data_offset, funcname);
4696 data_offset += strlen(funcname) + 1;
4697 data_section->data_ptr = data_section->data + data_offset;
4698 next();
4699 } else if (tok == TOK_LSTR) {
4700 t = VT_INT;
4701 goto str_init;
4702 } else if (tok == TOK_STR) {
4703 /* string parsing */
4704 t = VT_BYTE;
4705 str_init:
4706 type_size(t, &align);
4707 data_offset = data_section->data_ptr - data_section->data;
4708 data_offset = (data_offset + align - 1) & -align;
4709 fc = data_offset;
4710 /* we must declare it as an array first to use initializer parser */
4711 t = VT_ARRAY | mk_pointer(t);
4712 decl_initializer(t, data_section, data_offset, 1, 0);
4713 data_offset += type_size(t, &align);
4714 /* put it as pointer */
4715 vpush_ref(t & ~VT_ARRAY, data_section, fc);
4716 data_section->data_ptr = data_section->data + data_offset;
4717 } else {
4718 t = tok;
4719 next();
4720 if (t == '(') {
4721 /* cast ? */
4722 if (parse_btype(&t, &ad)) {
4723 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4724 skip(')');
4725 /* check ISOC99 compound literal */
4726 if (tok == '{') {
4727 /* data is allocated locally by default */
4728 if (global_expr)
4729 r = VT_CONST;
4730 else
4731 r = VT_LOCAL;
4732 /* all except arrays are lvalues */
4733 if (!(ft & VT_ARRAY))
4734 r |= lvalue_type(ft);
4735 memset(&ad, 0, sizeof(AttributeDef));
4736 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
4737 } else {
4738 unary();
4739 gen_cast(ft);
4741 } else {
4742 gexpr();
4743 skip(')');
4745 } else if (t == '*') {
4746 unary();
4747 indir();
4748 } else if (t == '&') {
4749 unary();
4750 /* functions names must be treated as function pointers,
4751 except for unary '&' and sizeof. Since we consider that
4752 functions are not lvalues, we only have to handle it
4753 there and in function calls. */
4754 /* arrays can also be used although they are not lvalues */
4755 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
4756 !(vtop->t & VT_ARRAY))
4757 test_lvalue();
4758 vtop->t = mk_pointer(vtop->t);
4759 gaddrof();
4760 } else
4761 if (t == '!') {
4762 unary();
4763 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
4764 vtop->c.i = !vtop->c.i;
4765 else if ((vtop->r & VT_VALMASK) == VT_CMP)
4766 vtop->c.i = vtop->c.i ^ 1;
4767 else
4768 vset(VT_INT, VT_JMP, gtst(1, 0));
4769 } else
4770 if (t == '~') {
4771 unary();
4772 vpushi(-1);
4773 gen_op('^');
4774 } else
4775 if (t == '+') {
4776 unary();
4777 } else
4778 if (t == TOK_SIZEOF) {
4779 if (tok == '(') {
4780 next();
4781 if (parse_btype(&t, &ad)) {
4782 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4783 } else {
4784 /* XXX: some code could be generated: add eval
4785 flag */
4786 gexpr();
4787 t = vtop->t;
4788 vpop();
4790 skip(')');
4791 } else {
4792 unary();
4793 t = vtop->t;
4794 vpop();
4796 vpushi(type_size(t, &t));
4797 } else
4798 if (t == TOK_INC || t == TOK_DEC) {
4799 unary();
4800 inc(0, t);
4801 } else if (t == '-') {
4802 vpushi(0);
4803 unary();
4804 gen_op('-');
4805 } else
4807 if (t < TOK_UIDENT)
4808 expect("identifier");
4809 s = sym_find(t);
4810 if (!s) {
4811 if (tok != '(')
4812 error("'%s' undeclared", get_tok_str(t, NULL));
4813 /* for simple function calls, we tolerate undeclared
4814 external reference */
4815 p = anon_sym++;
4816 sym_push1(&global_stack, p, 0, FUNC_OLD);
4817 /* int() function */
4818 s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT), 0);
4820 vset(s->t, s->r, s->c);
4821 /* if forward reference, we must point to s */
4822 if (vtop->r & VT_SYM)
4823 vtop->c.sym = s;
4827 /* post operations */
4828 while (1) {
4829 if (tok == TOK_INC || tok == TOK_DEC) {
4830 inc(1, tok);
4831 next();
4832 } else if (tok == '.' || tok == TOK_ARROW) {
4833 /* field */
4834 if (tok == TOK_ARROW)
4835 indir();
4836 test_lvalue();
4837 gaddrof();
4838 next();
4839 /* expect pointer on structure */
4840 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
4841 expect("struct or union");
4842 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4843 /* find field */
4844 tok |= SYM_FIELD;
4845 while ((s = s->next) != NULL) {
4846 if (s->v == tok)
4847 break;
4849 if (!s)
4850 error("field not found");
4851 /* add field offset to pointer */
4852 vtop->t = char_pointer_type; /* change type to 'char *' */
4853 vpushi(s->c);
4854 gen_op('+');
4855 /* change type to field type, and set to lvalue */
4856 vtop->t = s->t;
4857 /* an array is never an lvalue */
4858 if (!(vtop->t & VT_ARRAY))
4859 vtop->r |= lvalue_type(vtop->t);
4860 next();
4861 } else if (tok == '[') {
4862 next();
4863 gexpr();
4864 gen_op('+');
4865 indir();
4866 skip(']');
4867 } else if (tok == '(') {
4868 SValue ret;
4869 Sym *sa;
4871 /* function call */
4872 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
4873 /* pointer test (no array accepted) */
4874 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4875 vtop->t = pointed_type(vtop->t);
4876 if ((vtop->t & VT_BTYPE) != VT_FUNC)
4877 goto error_func;
4878 } else {
4879 error_func:
4880 expect("function pointer");
4882 } else {
4883 vtop->r &= ~VT_LVAL; /* no lvalue */
4885 /* get return type */
4886 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
4887 save_regs(0); /* save used temporary registers */
4888 gfunc_start(&gf, s->r);
4889 next();
4890 sa = s->next; /* first parameter */
4891 #ifdef INVERT_FUNC_PARAMS
4893 int parlevel;
4894 Sym *args, *s1;
4895 ParseState saved_parse_state;
4896 TokenString str;
4898 /* read each argument and store it on a stack */
4899 /* XXX: merge it with macro args ? */
4900 args = NULL;
4901 if (tok != ')') {
4902 for(;;) {
4903 tok_str_new(&str);
4904 parlevel = 0;
4905 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
4906 tok != -1) {
4907 if (tok == '(')
4908 parlevel++;
4909 else if (tok == ')')
4910 parlevel--;
4911 tok_str_add_tok(&str);
4912 next();
4914 tok_str_add(&str, -1); /* end of file added */
4915 tok_str_add(&str, 0);
4916 s1 = sym_push2(&args, 0, 0, (int)str.str);
4917 s1->next = sa; /* add reference to argument */
4918 if (sa)
4919 sa = sa->next;
4920 if (tok == ')')
4921 break;
4922 skip(',');
4926 /* now generate code in reverse order by reading the stack */
4927 save_parse_state(&saved_parse_state);
4928 while (args) {
4929 macro_ptr = (int *)args->c;
4930 next();
4931 expr_eq();
4932 if (tok != -1)
4933 expect("',' or ')'");
4934 gfunc_param_typed(&gf, s, args->next);
4935 s1 = args->prev;
4936 free((int *)args->c);
4937 free(args);
4938 args = s1;
4940 restore_parse_state(&saved_parse_state);
4942 #endif
4943 /* compute first implicit argument if a structure is returned */
4944 if ((s->t & VT_BTYPE) == VT_STRUCT) {
4945 /* get some space for the returned structure */
4946 size = type_size(s->t, &align);
4947 loc = (loc - size) & -align;
4948 ret.t = s->t;
4949 ret.r = VT_LOCAL | VT_LVAL;
4950 /* pass it as 'int' to avoid structure arg passing
4951 problems */
4952 vset(VT_INT, VT_LOCAL, loc);
4953 ret.c = vtop->c;
4954 gfunc_param(&gf);
4955 } else {
4956 ret.t = s->t;
4957 ret.r2 = VT_CONST;
4958 /* return in register */
4959 if (is_float(ret.t)) {
4960 ret.r = REG_FRET;
4961 } else {
4962 if ((ret.t & VT_BTYPE) == VT_LLONG)
4963 ret.r2 = REG_LRET;
4964 ret.r = REG_IRET;
4966 ret.c.i = 0;
4968 #ifndef INVERT_FUNC_PARAMS
4969 if (tok != ')') {
4970 for(;;) {
4971 expr_eq();
4972 gfunc_param_typed(&gf, s, sa);
4973 if (sa)
4974 sa = sa->next;
4975 if (tok == ')')
4976 break;
4977 skip(',');
4980 #endif
4981 if (sa)
4982 error("too few arguments to function");
4983 skip(')');
4984 gfunc_call(&gf);
4985 /* return value */
4986 vsetc(ret.t, ret.r, &ret.c);
4987 vtop->r2 = ret.r2;
4988 } else {
4989 break;
4994 void uneq(void)
4996 int t;
4998 unary();
4999 if (tok == '=' ||
5000 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5001 tok == TOK_A_XOR || tok == TOK_A_OR ||
5002 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5003 test_lvalue();
5004 t = tok;
5005 next();
5006 if (t == '=') {
5007 expr_eq();
5008 } else {
5009 vdup();
5010 expr_eq();
5011 gen_op(t & 0x7f);
5013 vstore();
5017 void sum(int l)
5019 int t;
5021 if (l == 0)
5022 uneq();
5023 else {
5024 sum(--l);
5025 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5026 (l == 1 && (tok == '+' || tok == '-')) ||
5027 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5028 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5029 tok == TOK_ULT || tok == TOK_UGE)) ||
5030 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5031 (l == 5 && tok == '&') ||
5032 (l == 6 && tok == '^') ||
5033 (l == 7 && tok == '|') ||
5034 (l == 8 && tok == TOK_LAND) ||
5035 (l == 9 && tok == TOK_LOR)) {
5036 t = tok;
5037 next();
5038 sum(l);
5039 gen_op(t);
5044 /* only used if non constant */
5045 void eand(void)
5047 int t;
5049 sum(8);
5050 t = 0;
5051 while (1) {
5052 if (tok != TOK_LAND) {
5053 if (t) {
5054 t = gtst(1, t);
5055 vset(VT_INT, VT_JMPI, t);
5057 break;
5059 t = gtst(1, t);
5060 next();
5061 sum(8);
5065 void eor(void)
5067 int t;
5069 eand();
5070 t = 0;
5071 while (1) {
5072 if (tok != TOK_LOR) {
5073 if (t) {
5074 t = gtst(0, t);
5075 vset(VT_INT, VT_JMP, t);
5077 break;
5079 t = gtst(0, t);
5080 next();
5081 eand();
5085 /* XXX: better constant handling */
5086 void expr_eq(void)
5088 int t, u, c, r1, r2, rc;
5090 if (const_wanted) {
5091 sum(10);
5092 if (tok == '?') {
5093 c = vtop->c.i;
5094 vpop();
5095 next();
5096 gexpr();
5097 t = vtop->c.i;
5098 vpop();
5099 skip(':');
5100 expr_eq();
5101 if (c)
5102 vtop->c.i = t;
5104 } else {
5105 eor();
5106 if (tok == '?') {
5107 next();
5108 save_regs(1); /* we need to save all registers here except
5109 at the top because it is a branch point */
5110 t = gtst(1, 0);
5111 gexpr();
5112 /* XXX: long long handling ? */
5113 rc = RC_INT;
5114 if (is_float(vtop->t))
5115 rc = RC_FLOAT;
5116 r1 = gv(rc);
5117 vtop--; /* no vpop so that FP stack is not flushed */
5118 skip(':');
5119 u = gjmp(0);
5121 gsym(t);
5122 expr_eq();
5123 r2 = gv(rc);
5124 move_reg(r1, r2);
5125 vtop->r = r1;
5126 gsym(u);
5131 void gexpr(void)
5133 while (1) {
5134 expr_eq();
5135 if (tok != ',')
5136 break;
5137 vpop();
5138 next();
5142 /* parse a constant expression and return value in vtop */
5143 void expr_const1(void)
5145 int a;
5146 a = const_wanted;
5147 const_wanted = 1;
5148 expr_eq();
5149 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5150 expect("constant");
5151 const_wanted = a;
5154 /* parse an integer constant and return its value */
5155 int expr_const(void)
5157 int c;
5158 expr_const1();
5159 c = vtop->c.i;
5160 vpop();
5161 return c;
5164 /* return the label token if current token is a label, otherwise
5165 return zero */
5166 int is_label(void)
5168 int t;
5169 CValue c;
5171 /* fast test first */
5172 if (tok < TOK_UIDENT)
5173 return 0;
5174 /* no need to save tokc since we expect an identifier */
5175 t = tok;
5176 c = tokc;
5177 next();
5178 if (tok == ':') {
5179 next();
5180 return t;
5181 } else {
5182 /* XXX: may not work in all cases (macros ?) */
5183 tok1 = tok;
5184 tok1c = tokc;
5185 tok = t;
5186 tokc = c;
5187 return 0;
5191 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5193 int a, b, c, d;
5194 Sym *s;
5196 /* generate line number info */
5197 if (do_debug &&
5198 (last_line_num != file->line_num || last_ind != ind)) {
5199 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5200 last_ind = ind;
5201 last_line_num = file->line_num;
5204 if (tok == TOK_IF) {
5205 /* if test */
5206 next();
5207 skip('(');
5208 gexpr();
5209 skip(')');
5210 a = gtst(1, 0);
5211 block(bsym, csym, case_sym, def_sym, case_reg);
5212 c = tok;
5213 if (c == TOK_ELSE) {
5214 next();
5215 d = gjmp(0);
5216 gsym(a);
5217 block(bsym, csym, case_sym, def_sym, case_reg);
5218 gsym(d); /* patch else jmp */
5219 } else
5220 gsym(a);
5221 } else if (tok == TOK_WHILE) {
5222 next();
5223 d = ind;
5224 skip('(');
5225 gexpr();
5226 skip(')');
5227 a = gtst(1, 0);
5228 b = 0;
5229 block(&a, &b, case_sym, def_sym, case_reg);
5230 gjmp_addr(d);
5231 gsym(a);
5232 gsym_addr(b, d);
5233 } else if (tok == '{') {
5234 next();
5235 /* declarations */
5236 s = local_stack.top;
5237 while (tok != '}') {
5238 decl(VT_LOCAL);
5239 if (tok != '}')
5240 block(bsym, csym, case_sym, def_sym, case_reg);
5242 /* pop locally defined symbols */
5243 sym_pop(&local_stack, s);
5244 next();
5245 } else if (tok == TOK_RETURN) {
5246 next();
5247 if (tok != ';') {
5248 gexpr();
5249 gen_assign_cast(func_vt);
5250 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5251 /* if returning structure, must copy it to implicit
5252 first pointer arg location */
5253 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5254 indir();
5255 vswap();
5256 /* copy structure value to pointer */
5257 vstore();
5258 } else if (is_float(func_vt)) {
5259 gv(RC_FRET);
5260 } else {
5261 gv(RC_IRET);
5263 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5265 skip(';');
5266 rsym = gjmp(rsym); /* jmp */
5267 } else if (tok == TOK_BREAK) {
5268 /* compute jump */
5269 if (!bsym)
5270 error("cannot break");
5271 *bsym = gjmp(*bsym);
5272 next();
5273 skip(';');
5274 } else if (tok == TOK_CONTINUE) {
5275 /* compute jump */
5276 if (!csym)
5277 error("cannot continue");
5278 *csym = gjmp(*csym);
5279 next();
5280 skip(';');
5281 } else if (tok == TOK_FOR) {
5282 int e;
5283 next();
5284 skip('(');
5285 if (tok != ';') {
5286 gexpr();
5287 vpop();
5289 skip(';');
5290 d = ind;
5291 c = ind;
5292 a = 0;
5293 b = 0;
5294 if (tok != ';') {
5295 gexpr();
5296 a = gtst(1, 0);
5298 skip(';');
5299 if (tok != ')') {
5300 e = gjmp(0);
5301 c = ind;
5302 gexpr();
5303 vpop();
5304 gjmp_addr(d);
5305 gsym(e);
5307 skip(')');
5308 block(&a, &b, case_sym, def_sym, case_reg);
5309 gjmp_addr(c);
5310 gsym(a);
5311 gsym_addr(b, c);
5312 } else
5313 if (tok == TOK_DO) {
5314 next();
5315 a = 0;
5316 b = 0;
5317 d = ind;
5318 block(&a, &b, case_sym, def_sym, case_reg);
5319 skip(TOK_WHILE);
5320 skip('(');
5321 gsym(b);
5322 gexpr();
5323 c = gtst(0, 0);
5324 gsym_addr(c, d);
5325 skip(')');
5326 gsym(a);
5327 skip(';');
5328 } else
5329 if (tok == TOK_SWITCH) {
5330 next();
5331 skip('(');
5332 gexpr();
5333 /* XXX: other types than integer */
5334 case_reg = gv(RC_INT);
5335 vpop();
5336 skip(')');
5337 a = 0;
5338 b = gjmp(0); /* jump to first case */
5339 c = 0;
5340 block(&a, csym, &b, &c, case_reg);
5341 /* if no default, jmp after switch */
5342 if (c == 0)
5343 c = ind;
5344 /* default label */
5345 gsym_addr(b, c);
5346 /* break label */
5347 gsym(a);
5348 } else
5349 if (tok == TOK_CASE) {
5350 int v1, v2;
5351 if (!case_sym)
5352 expect("switch");
5353 next();
5354 v1 = expr_const();
5355 v2 = v1;
5356 if (gnu_ext && tok == TOK_DOTS) {
5357 next();
5358 v2 = expr_const();
5359 if (v2 < v1)
5360 warning("empty case range");
5362 /* since a case is like a label, we must skip it with a jmp */
5363 b = gjmp(0);
5364 gsym(*case_sym);
5365 vset(VT_INT, case_reg, 0);
5366 vpushi(v1);
5367 if (v1 == v2) {
5368 gen_op(TOK_EQ);
5369 *case_sym = gtst(1, 0);
5370 } else {
5371 gen_op(TOK_GE);
5372 *case_sym = gtst(1, 0);
5373 vset(VT_INT, case_reg, 0);
5374 vpushi(v2);
5375 gen_op(TOK_LE);
5376 *case_sym = gtst(1, *case_sym);
5378 gsym(b);
5379 skip(':');
5380 block(bsym, csym, case_sym, def_sym, case_reg);
5381 } else
5382 if (tok == TOK_DEFAULT) {
5383 next();
5384 skip(':');
5385 if (!def_sym)
5386 expect("switch");
5387 if (*def_sym)
5388 error("too many 'default'");
5389 *def_sym = ind;
5390 block(bsym, csym, case_sym, def_sym, case_reg);
5391 } else
5392 if (tok == TOK_GOTO) {
5393 next();
5394 s = sym_find1(&label_stack, tok);
5395 /* put forward definition if needed */
5396 if (!s)
5397 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5398 /* label already defined */
5399 if (s->t & LABEL_FORWARD)
5400 s->c = gjmp(s->c);
5401 else
5402 gjmp_addr(s->c);
5403 next();
5404 skip(';');
5405 } else {
5406 b = is_label();
5407 if (b) {
5408 /* label case */
5409 s = sym_find1(&label_stack, b);
5410 if (s) {
5411 if (!(s->t & LABEL_FORWARD))
5412 error("multiple defined label");
5413 gsym(s->c);
5414 s->c = ind;
5415 s->t = 0;
5416 } else {
5417 sym_push1(&label_stack, b, 0, ind);
5419 /* we accept this, but it is a mistake */
5420 if (tok == '}')
5421 warning("deprecated use of label at end of compound statement");
5422 else
5423 block(bsym, csym, case_sym, def_sym, case_reg);
5424 } else {
5425 /* expression case */
5426 if (tok != ';') {
5427 gexpr();
5428 vpop();
5430 skip(';');
5435 /* t is the array or struct type. c is the array or struct
5436 address. cur_index/cur_field is the pointer to the current
5437 value. 'size_only' is true if only size info is needed (only used
5438 in arrays) */
5439 void decl_designator(int t, Section *sec, unsigned long c,
5440 int *cur_index, Sym **cur_field,
5441 int size_only)
5443 Sym *s, *f;
5444 int notfirst, index, align, l;
5446 notfirst = 0;
5447 if (gnu_ext && (l = is_label()) != 0)
5448 goto struct_field;
5450 while (tok == '[' || tok == '.') {
5451 if (tok == '[') {
5452 if (!(t & VT_ARRAY))
5453 expect("array type");
5454 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5455 next();
5456 index = expr_const();
5457 if (index < 0 || (s->c >= 0 && index >= s->c))
5458 expect("invalid index");
5459 skip(']');
5460 if (!notfirst)
5461 *cur_index = index;
5462 t = pointed_type(t);
5463 c += index * type_size(t, &align);
5464 } else {
5465 next();
5466 l = tok;
5467 next();
5468 struct_field:
5469 if ((t & VT_BTYPE) != VT_STRUCT)
5470 expect("struct/union type");
5471 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5472 l |= SYM_FIELD;
5473 f = s->next;
5474 while (f) {
5475 if (f->v == l)
5476 break;
5477 f = f->next;
5479 if (!f)
5480 expect("field");
5481 if (!notfirst)
5482 *cur_field = f;
5483 t = f->t | (t & ~VT_TYPE);
5484 c += f->c;
5486 notfirst = 1;
5488 if (notfirst) {
5489 if (tok == '=') {
5490 next();
5491 } else {
5492 if (!gnu_ext)
5493 expect("=");
5495 } else {
5496 if (t & VT_ARRAY) {
5497 index = *cur_index;
5498 t = pointed_type(t);
5499 c += index * type_size(t, &align);
5500 } else {
5501 f = *cur_field;
5502 if (!f)
5503 error("too many field init");
5504 t = f->t | (t & ~VT_TYPE);
5505 c += f->c;
5508 decl_initializer(t, sec, c, 0, size_only);
5511 #define EXPR_VAL 0
5512 #define EXPR_CONST 1
5513 #define EXPR_ANY 2
5515 /* store a value or an expression directly in global data or in local array */
5516 void init_putv(int t, Section *sec, unsigned long c,
5517 int v, int expr_type)
5519 int saved_global_expr, bt;
5520 void *ptr;
5522 switch(expr_type) {
5523 case EXPR_VAL:
5524 vpushi(v);
5525 break;
5526 case EXPR_CONST:
5527 /* compound literals must be allocated globally in this case */
5528 saved_global_expr = global_expr;
5529 global_expr = 1;
5530 expr_const1();
5531 global_expr = saved_global_expr;
5532 break;
5533 case EXPR_ANY:
5534 expr_eq();
5535 break;
5538 if (sec) {
5539 /* XXX: not portable */
5540 /* XXX: generate error if incorrect relocation */
5541 gen_assign_cast(t);
5542 bt = t & VT_BTYPE;
5543 ptr = sec->data + c;
5544 if ((vtop->r & VT_SYM) &&
5545 (bt == VT_BYTE ||
5546 bt == VT_SHORT ||
5547 bt == VT_DOUBLE ||
5548 bt == VT_LDOUBLE ||
5549 bt == VT_LLONG))
5550 error("initializer element is not computable at load time");
5551 switch(bt) {
5552 case VT_BYTE:
5553 *(char *)ptr = vtop->c.i;
5554 break;
5555 case VT_SHORT:
5556 *(short *)ptr = vtop->c.i;
5557 break;
5558 case VT_DOUBLE:
5559 *(double *)ptr = vtop->c.d;
5560 break;
5561 case VT_LDOUBLE:
5562 *(long double *)ptr = vtop->c.ld;
5563 break;
5564 case VT_LLONG:
5565 *(long long *)ptr = vtop->c.ll;
5566 break;
5567 default:
5568 if (vtop->r & VT_SYM) {
5569 greloc(sec, vtop->c.sym, c, R_DATA_32);
5570 *(int *)ptr = 0;
5571 } else {
5572 *(int *)ptr = vtop->c.i;
5574 break;
5576 vtop--;
5577 } else {
5578 vset(t, VT_LOCAL, c);
5579 vswap();
5580 vstore();
5581 vpop();
5585 /* put zeros for variable based init */
5586 void init_putz(int t, Section *sec, unsigned long c, int size)
5588 GFuncContext gf;
5590 if (sec) {
5591 /* nothing to do because globals are already set to zero */
5592 } else {
5593 gfunc_start(&gf, FUNC_CDECL);
5594 vpushi(size);
5595 gfunc_param(&gf);
5596 vpushi(0);
5597 gfunc_param(&gf);
5598 vset(VT_INT, VT_LOCAL, c);
5599 gfunc_param(&gf);
5600 vpushi((int)&memset);
5601 gfunc_call(&gf);
5605 /* 't' contains the type and storage info. 'c' is the offset of the
5606 object in section 'sec'. If 'sec' is NULL, it means stack based
5607 allocation. 'first' is true if array '{' must be read (multi
5608 dimension implicit array init handling). 'size_only' is true if
5609 size only evaluation is wanted (only for arrays). */
5610 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only)
5612 int index, array_length, n, no_oblock, nb, parlevel, i;
5613 int t1, size1, align1, expr_type;
5614 Sym *s, *f;
5615 TokenSym *ts;
5617 if (t & VT_ARRAY) {
5618 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5619 n = s->c;
5620 array_length = 0;
5621 t1 = pointed_type(t);
5622 size1 = type_size(t1, &align1);
5624 no_oblock = 1;
5625 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5626 tok == '{') {
5627 skip('{');
5628 no_oblock = 0;
5631 /* only parse strings here if correct type (otherwise: handle
5632 them as ((w)char *) expressions */
5633 if ((tok == TOK_LSTR &&
5634 (t1 & VT_BTYPE) == VT_INT) ||
5635 (tok == TOK_STR &&
5636 (t1 & VT_BTYPE) == VT_BYTE)) {
5637 /* XXX: move multiple string parsing in parser ? */
5638 while (tok == TOK_STR || tok == TOK_LSTR) {
5639 ts = tokc.ts;
5640 /* compute maximum number of chars wanted */
5641 nb = ts->len;
5642 if (n >= 0 && nb > (n - array_length))
5643 nb = n - array_length;
5644 if (!size_only) {
5645 if (ts->len > nb)
5646 warning("initializer-string for array is too long");
5647 for(i=0;i<nb;i++) {
5648 init_putv(t1, sec, c + (array_length + i) * size1,
5649 ts->str[i], EXPR_VAL);
5652 array_length += nb;
5653 next();
5655 /* only add trailing zero if enough storage (no
5656 warning in this case since it is standard) */
5657 if (n < 0 || array_length < n) {
5658 if (!size_only) {
5659 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5661 array_length++;
5663 } else {
5664 index = 0;
5665 while (tok != '}') {
5666 decl_designator(t, sec, c, &index, NULL, size_only);
5667 if (n >= 0 && index >= n)
5668 error("index too large");
5669 /* must put zero in holes (note that doing it that way
5670 ensures that it even works with designators) */
5671 if (!size_only && array_length < index) {
5672 init_putz(t1, sec, c + array_length * size1,
5673 (index - array_length) * size1);
5675 index++;
5676 if (index > array_length)
5677 array_length = index;
5678 /* special test for multi dimensional arrays (may not
5679 be strictly correct if designators are used at the
5680 same time) */
5681 if (index >= n && no_oblock)
5682 break;
5683 if (tok == '}')
5684 break;
5685 skip(',');
5688 if (!no_oblock)
5689 skip('}');
5690 /* put zeros at the end */
5691 if (!size_only && n >= 0 && array_length < n) {
5692 init_putz(t1, sec, c + array_length * size1,
5693 (n - array_length) * size1);
5695 /* patch type size if needed */
5696 if (n < 0)
5697 s->c = array_length;
5698 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
5699 /* XXX: union needs only one init */
5700 next();
5701 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5702 f = s->next;
5703 array_length = 0;
5704 index = 0;
5705 n = s->c;
5706 while (tok != '}') {
5707 decl_designator(t, sec, c, NULL, &f, size_only);
5708 /* fill with zero between fields */
5709 index = f->c;
5710 if (!size_only && array_length < index) {
5711 init_putz(t, sec, c + array_length,
5712 index - array_length);
5714 index = index + type_size(f->t, &align1);
5715 if (index > array_length)
5716 array_length = index;
5717 if (tok == '}')
5718 break;
5719 skip(',');
5720 f = f->next;
5722 /* put zeros at the end */
5723 if (!size_only && array_length < n) {
5724 init_putz(t, sec, c + array_length,
5725 n - array_length);
5727 skip('}');
5728 } else if (tok == '{') {
5729 next();
5730 decl_initializer(t, sec, c, first, size_only);
5731 skip('}');
5732 } else if (size_only) {
5733 /* just skip expression */
5734 parlevel = 0;
5735 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
5736 tok != -1) {
5737 if (tok == '(')
5738 parlevel++;
5739 else if (tok == ')')
5740 parlevel--;
5741 next();
5743 } else {
5744 /* currently, we always use constant expression for globals
5745 (may change for scripting case) */
5746 expr_type = EXPR_CONST;
5747 if (!sec)
5748 expr_type = EXPR_ANY;
5749 init_putv(t, sec, c, 0, expr_type);
5753 /* parse an initializer for type 't' if 'has_init' is true, and
5754 allocate space in local or global data space ('r' is either
5755 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5756 variable 'v' of scope 'scope' is declared before initializers are
5757 parsed. If 'v' is zero, then a reference to the new object is put
5758 in the value stack. */
5759 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
5760 int v, int scope)
5762 int size, align, addr, data_offset;
5763 int level;
5764 ParseState saved_parse_state;
5765 TokenString init_str;
5766 Section *sec;
5768 size = type_size(t, &align);
5769 /* If unknown size, we must evaluate it before
5770 evaluating initializers because
5771 initializers can generate global data too
5772 (e.g. string pointers or ISOC99 compound
5773 literals). It also simplifies local
5774 initializers handling */
5775 tok_str_new(&init_str);
5776 if (size < 0) {
5777 if (!has_init)
5778 error("unknown type size");
5779 /* get all init string */
5780 level = 0;
5781 while (level > 0 || (tok != ',' && tok != ';')) {
5782 if (tok < 0)
5783 error("unexpected end of file in initializer");
5784 tok_str_add_tok(&init_str);
5785 if (tok == '{')
5786 level++;
5787 else if (tok == '}') {
5788 if (level == 0)
5789 break;
5790 level--;
5792 next();
5794 tok_str_add(&init_str, -1);
5795 tok_str_add(&init_str, 0);
5797 /* compute size */
5798 save_parse_state(&saved_parse_state);
5800 macro_ptr = init_str.str;
5801 next();
5802 decl_initializer(t, NULL, 0, 1, 1);
5803 /* prepare second initializer parsing */
5804 macro_ptr = init_str.str;
5805 next();
5807 /* if still unknown size, error */
5808 size = type_size(t, &align);
5809 if (size < 0)
5810 error("unknown type size");
5812 /* take into account specified alignment if bigger */
5813 if (ad->aligned > align)
5814 align = ad->aligned;
5815 if ((r & VT_VALMASK) == VT_LOCAL) {
5816 sec = NULL;
5817 if (do_bounds_check && (t & VT_ARRAY))
5818 loc--;
5819 #ifdef TCC_TARGET_IL
5820 /* XXX: ugly patch to allocate local variables for IL, just
5821 for testing */
5822 addr = loc;
5823 loc++;
5824 #else
5825 loc = (loc - size) & -align;
5826 addr = loc;
5827 #endif
5828 /* handles bounds */
5829 /* XXX: currently, since we do only one pass, we cannot track
5830 '&' operators, so we add only arrays */
5831 if (do_bounds_check && (t & VT_ARRAY)) {
5832 int *bounds_ptr;
5833 /* add padding between regions */
5834 loc--;
5835 /* then add local bound info */
5836 bounds_ptr = (int *)lbounds_section->data_ptr;
5837 *bounds_ptr++ = addr;
5838 *bounds_ptr++ = size;
5839 lbounds_section->data_ptr = (unsigned char *)bounds_ptr;
5841 } else {
5842 /* compute section */
5843 sec = ad->section;
5844 if (!sec) {
5845 if (has_init)
5846 sec = data_section;
5847 else
5848 sec = bss_section;
5850 data_offset = sec->data_ptr - sec->data;
5851 data_offset = (data_offset + align - 1) & -align;
5852 addr = data_offset;
5853 /* very important to increment global pointer at this time
5854 because initializers themselves can create new initializers */
5855 data_offset += size;
5856 /* handles bounds */
5857 if (do_bounds_check) {
5858 int *bounds_ptr;
5859 /* first, we need to add at least one byte between each region */
5860 data_offset++;
5861 /* then add global bound info */
5862 bounds_ptr = (int *)bounds_section->data_ptr;
5863 /* XXX: add relocation */
5864 *bounds_ptr++ = addr + (unsigned long)sec->data;
5865 *bounds_ptr++ = size;
5866 bounds_section->data_ptr = (unsigned char *)bounds_ptr;
5868 sec->data_ptr = sec->data + data_offset;
5870 if (v) {
5871 Sym *sym;
5873 if (!sec) {
5874 /* local variable */
5875 sym_push(v, t, r, addr);
5876 } else {
5877 if (scope == VT_CONST) {
5878 /* global scope: see if already defined */
5879 sym = sym_find(v);
5880 if (!sym)
5881 goto do_def;
5882 if (!is_compatible_types(sym->t, t))
5883 error("incompatible types for redefinition of '%s'",
5884 get_tok_str(v, NULL));
5885 if (!(sym->t & VT_EXTERN))
5886 error("redefinition of '%s'", get_tok_str(v, NULL));
5887 sym->t &= ~VT_EXTERN;
5888 } else {
5889 do_def:
5890 sym = sym_push(v, t, r | VT_SYM, 0);
5892 put_extern_sym(sym, sec, addr);
5894 } else {
5895 if (!sec) {
5896 /* push local reference */
5897 vset(t, r, addr);
5898 } else {
5899 /* push global reference */
5900 vpush_ref(t, sec, addr);
5903 if (has_init) {
5904 decl_initializer(t, sec, addr, 1, 0);
5905 /* restore parse state if needed */
5906 if (init_str.str) {
5907 free(init_str.str);
5908 restore_parse_state(&saved_parse_state);
5913 void put_func_debug(int t)
5915 char buf[512];
5917 /* stabs info */
5918 /* XXX: we put here a dummy type */
5919 snprintf(buf, sizeof(buf), "%s:%c1",
5920 funcname, t & VT_STATIC ? 'f' : 'F');
5921 put_stabs(buf, N_FUN, 0, file->line_num, ind);
5922 func_ind = ind;
5923 last_ind = 0;
5924 last_line_num = 0;
5927 /* not finished : try to put some local vars in registers */
5928 //#define CONFIG_REG_VARS
5930 #ifdef CONFIG_REG_VARS
5931 void add_var_ref(int t)
5933 printf("%s:%d: &%s\n",
5934 file->filename, file->line_num,
5935 get_tok_str(t, NULL));
5938 /* first pass on a function with heuristic to extract variable usage
5939 and pointer references to local variables for register allocation */
5940 void analyse_function(void)
5942 int level, t;
5944 for(;;) {
5945 if (tok == -1)
5946 break;
5947 /* any symbol coming after '&' is considered as being a
5948 variable whose reference is taken. It is highly unaccurate
5949 but it is difficult to do better without a complete parse */
5950 if (tok == '&') {
5951 next();
5952 /* if '& number', then no need to examine next tokens */
5953 if (tok == TOK_CINT ||
5954 tok == TOK_CUINT ||
5955 tok == TOK_CLLONG ||
5956 tok == TOK_CULLONG) {
5957 continue;
5958 } else if (tok >= TOK_UIDENT) {
5959 /* if '& ident [' or '& ident ->', then ident address
5960 is not needed */
5961 t = tok;
5962 next();
5963 if (tok != '[' && tok != TOK_ARROW)
5964 add_var_ref(t);
5965 } else {
5966 level = 0;
5967 while (tok != '}' && tok != ';' &&
5968 !((tok == ',' || tok == ')') && level == 0)) {
5969 if (tok >= TOK_UIDENT) {
5970 add_var_ref(tok);
5971 } else if (tok == '(') {
5972 level++;
5973 } else if (tok == ')') {
5974 level--;
5976 next();
5979 } else {
5980 next();
5984 #endif
5986 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5987 void decl(int l)
5989 int t, b, v, has_init, r;
5990 Sym *sym;
5991 AttributeDef ad;
5993 while (1) {
5994 if (!parse_btype(&b, &ad)) {
5995 /* skip redundant ';' */
5996 /* XXX: find more elegant solution */
5997 if (tok == ';') {
5998 next();
5999 continue;
6001 /* special test for old K&R protos without explicit int
6002 type. Only accepted when defining global data */
6003 if (l == VT_LOCAL || tok < TOK_DEFINE)
6004 break;
6005 b = VT_INT;
6007 if (((b & VT_BTYPE) == VT_ENUM ||
6008 (b & VT_BTYPE) == VT_STRUCT) &&
6009 tok == ';') {
6010 /* we accept no variable after */
6011 next();
6012 continue;
6014 while (1) { /* iterate thru each declaration */
6015 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6016 #if 0
6018 char buf[500];
6019 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6020 printf("type = '%s'\n", buf);
6022 #endif
6023 if (tok == '{') {
6024 #ifdef CONFIG_REG_VARS
6025 TokenString func_str;
6026 ParseState saved_parse_state;
6027 int block_level;
6028 #endif
6030 if (l == VT_LOCAL)
6031 error("cannot use local functions");
6032 if (!(t & VT_FUNC))
6033 expect("function definition");
6035 #ifdef CONFIG_REG_VARS
6036 /* parse all function code and record it */
6038 tok_str_new(&func_str);
6040 block_level = 0;
6041 for(;;) {
6042 int t;
6043 if (tok == -1)
6044 error("unexpected end of file");
6045 tok_str_add_tok(&func_str);
6046 t = tok;
6047 next();
6048 if (t == '{') {
6049 block_level++;
6050 } else if (t == '}') {
6051 block_level--;
6052 if (block_level == 0)
6053 break;
6056 tok_str_add(&func_str, -1);
6057 tok_str_add(&func_str, 0);
6059 save_parse_state(&saved_parse_state);
6061 macro_ptr = func_str.str;
6062 next();
6063 analyse_function();
6064 #endif
6066 /* compute text section */
6067 cur_text_section = ad.section;
6068 if (!cur_text_section)
6069 cur_text_section = text_section;
6070 ind = (int)cur_text_section->data_ptr;
6071 funcname = get_tok_str(v, NULL);
6072 sym = sym_find(v);
6073 if (sym) {
6074 /* if symbol is already defined, then put complete type */
6075 sym->t = t;
6076 } else {
6077 /* put function symbol */
6078 sym = sym_push1(&global_stack, v, t, 0);
6080 put_extern_sym(sym, cur_text_section,
6081 ind - (int)cur_text_section->data);
6082 sym->r = VT_SYM | VT_CONST;
6083 /* put debug symbol */
6084 if (do_debug)
6085 put_func_debug(t);
6086 /* push a dummy symbol to enable local sym storage */
6087 sym_push1(&local_stack, 0, 0, 0);
6088 gfunc_prolog(t);
6089 loc = 0;
6090 rsym = 0;
6091 #ifdef CONFIG_REG_VARS
6092 macro_ptr = func_str.str;
6093 next();
6094 #endif
6095 block(NULL, NULL, NULL, NULL, 0);
6096 gsym(rsym);
6097 gfunc_epilog();
6098 cur_text_section->data_ptr = (unsigned char *)ind;
6099 sym_pop(&label_stack, NULL); /* reset label stack */
6100 sym_pop(&local_stack, NULL); /* reset local stack */
6101 /* end of function */
6102 if (do_debug) {
6103 put_stabn(N_FUN, 0, 0, ind - func_ind);
6105 funcname = ""; /* for safety */
6106 func_vt = VT_VOID; /* for safety */
6107 ind = 0; /* for safety */
6109 #ifdef CONFIG_REG_VARS
6110 free(func_str.str);
6111 restore_parse_state(&saved_parse_state);
6112 #endif
6113 break;
6114 } else {
6115 if (b & VT_TYPEDEF) {
6116 /* save typedefed type */
6117 /* XXX: test storage specifiers ? */
6118 sym_push(v, t | VT_TYPEDEF, 0, 0);
6119 } else if ((t & VT_BTYPE) == VT_FUNC) {
6120 /* external function definition */
6121 external_sym(v, t, 0);
6122 } else {
6123 /* not lvalue if array */
6124 r = 0;
6125 if (!(t & VT_ARRAY))
6126 r |= lvalue_type(t);
6127 if (b & VT_EXTERN) {
6128 /* external variable */
6129 external_sym(v, t, r);
6130 } else {
6131 if (t & VT_STATIC)
6132 r |= VT_CONST;
6133 else
6134 r |= l;
6135 has_init = (tok == '=');
6136 if (has_init)
6137 next();
6138 decl_initializer_alloc(t, &ad, r,
6139 has_init, v, l);
6142 if (tok != ',') {
6143 skip(';');
6144 break;
6146 next();
6152 /* compile the C file opened in 'file'. Return non zero if errors. */
6153 int tcc_compile(TCCState *s)
6155 Sym *define_start;
6156 char buf[512];
6158 funcname = "";
6159 include_stack_ptr = include_stack;
6160 ifdef_stack_ptr = ifdef_stack;
6162 vtop = vstack - 1;
6163 anon_sym = SYM_FIRST_ANOM;
6165 /* file info: full path + filename */
6166 if (do_debug) {
6167 getcwd(buf, sizeof(buf));
6168 pstrcat(buf, sizeof(buf), "/");
6169 put_stabs(buf, N_SO, 0, 0, (unsigned long)text_section->data_ptr);
6170 put_stabs(file->filename, N_SO, 0, 0,
6171 (unsigned long)text_section->data_ptr);
6173 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6174 symbols can be safely used */
6175 put_elf_sym(symtab_section, 0, 0,
6176 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6177 SHN_ABS, file->filename);
6179 /* define common 'char *' type because it is often used internally
6180 for arrays and struct dereference */
6181 char_pointer_type = mk_pointer(VT_BYTE);
6183 define_start = define_stack.top;
6184 inp();
6185 ch = '\n'; /* needed to parse correctly first preprocessor command */
6186 next();
6187 decl(VT_CONST);
6188 if (tok != -1)
6189 expect("declaration");
6191 /* end of translation unit info */
6192 if (do_debug) {
6193 put_stabn(N_SO, 0, 0, (unsigned long)text_section->data_ptr);
6196 /* reset define stack, but leave -Dsymbols (may be incorrect if
6197 they are undefined) */
6198 sym_pop(&define_stack, define_start);
6200 sym_pop(&global_stack, NULL);
6202 return 0;
6205 int tcc_compile_file(TCCState *s, const char *filename1)
6207 int ret;
6208 file = tcc_open(filename1);
6209 if (!file)
6210 error("file '%s' not found", filename1);
6211 ret = tcc_compile(s);
6212 tcc_close(file);
6213 return ret;
6216 int tcc_compile_string(TCCState *s, const char *str)
6218 BufferedFile bf1, *bf = &bf1;
6219 int ret;
6221 /* init file structure */
6222 bf->fd = -1;
6223 bf->buf_ptr = (char *)str;
6224 bf->buf_end = (char *)str + strlen(bf->buffer);
6225 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6226 bf->line_num = 1;
6227 file = bf;
6229 ret = tcc_compile(s);
6231 /* currently, no need to close */
6232 return ret;
6235 /* define a symbol. A value can also be provided with the '=' operator */
6236 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6238 BufferedFile bf1, *bf = &bf1;
6240 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6241 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6242 /* default value */
6243 if (!value)
6244 value = "1";
6245 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6247 /* init file structure */
6248 bf->fd = -1;
6249 bf->buf_ptr = bf->buffer;
6250 bf->buf_end = bf->buffer + strlen(bf->buffer);
6251 bf->filename[0] = '\0';
6252 bf->line_num = 1;
6253 file = bf;
6255 include_stack_ptr = include_stack;
6257 /* parse with define parser */
6258 inp();
6259 ch = '\n'; /* needed to parse correctly first preprocessor command */
6260 next_nomacro();
6261 parse_define();
6262 file = NULL;
6265 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6267 TokenSym *ts;
6268 Sym *s;
6269 ts = tok_alloc(sym, 0);
6270 s = sym_find1(&define_stack, tok);
6271 /* undefine symbol by putting an invalid name */
6272 if (s)
6273 sym_undef(&define_stack, s);
6276 /* open a dynamic library so that its symbol are available for
6277 compiled programs */
6278 /* XXX: open the lib only to actually run the program */
6279 int tcc_add_dll(TCCState *s, const char *library_name)
6281 void *h;
6283 h = dlopen(library_name, RTLD_GLOBAL | RTLD_LAZY);
6284 if (!h)
6285 error((char *)dlerror());
6286 return 0;
6289 static int put_elf_str(Section *s, const char *sym)
6291 int c, offset;
6292 offset = s->data_ptr - s->data;
6293 for(;;) {
6294 c = *sym++;
6295 *s->data_ptr++ = c;
6296 if (c == '\0')
6297 break;
6299 return offset;
6302 /* elf symbol hashing function */
6303 static unsigned long elf_hash(const unsigned char *name)
6305 unsigned long h = 0, g;
6307 while (*name) {
6308 h = (h << 4) + *name++;
6309 g = h & 0xf0000000;
6310 if (g)
6311 h ^= g >> 24;
6312 h &= ~g;
6314 return h;
6317 /* return the symbol number */
6318 static int put_elf_sym(Section *s,
6319 unsigned long value, unsigned long size,
6320 int info, int other, int shndx, const char *name)
6322 int name_offset, sym_index;
6323 int nbuckets, h;
6324 Elf32_Sym *sym;
6325 Section *hs;
6327 sym = (Elf32_Sym *)s->data_ptr;
6328 if (name)
6329 name_offset = put_elf_str(s->link, name);
6330 else
6331 name_offset = 0;
6332 /* XXX: endianness */
6333 sym->st_name = name_offset;
6334 sym->st_value = value;
6335 sym->st_size = size;
6336 sym->st_info = info;
6337 sym->st_other = other;
6338 sym->st_shndx = shndx;
6339 sym_index = sym - (Elf32_Sym *)s->data;
6340 hs = s->hash;
6341 if (hs) {
6342 /* only add global or weak symbols */
6343 if (ELF32_ST_BIND(info) != STB_LOCAL) {
6344 /* add another hashing entry */
6345 nbuckets = ((int *)hs->data)[0];
6346 h = elf_hash(name) % nbuckets;
6347 ((int *)hs->data)[2 + nbuckets + sym_index] = ((int *)hs->data)[2 + h];
6348 ((int *)hs->data)[2 + h] = sym_index;
6350 /* but still add room for all symbols */
6351 ((int *)hs->data)[1]++;
6352 hs->data_ptr += sizeof(int);
6354 s->data_ptr += sizeof(Elf32_Sym);
6355 return sym_index;
6358 /* find global ELF symbol 'name' and return its index. Return 0 if not
6359 found. */
6360 static int find_elf_sym(Section *s, const char *name)
6362 Elf32_Sym *sym;
6363 Section *hs;
6364 int nbuckets, sym_index, h;
6365 const char *name1;
6367 hs = s->hash;
6368 if (!hs)
6369 return 0;
6370 nbuckets = ((int *)hs->data)[0];
6371 h = elf_hash(name) % nbuckets;
6372 sym_index = ((int *)hs->data)[2 + h];
6373 while (sym_index != 0) {
6374 sym = &((Elf32_Sym *)s->data)[sym_index];
6375 name1 = s->link->data + sym->st_name;
6376 if (!strcmp(name, name1))
6377 return sym_index;
6378 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
6380 return 0;
6383 /* return elf symbol value or error */
6384 static unsigned long get_elf_sym_val(const char *name)
6386 int sym_index;
6387 Elf32_Sym *sym;
6389 sym_index = find_elf_sym(symtab_section, name);
6390 if (!sym_index)
6391 error("%s not defined", name);
6392 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6393 return sym->st_value;
6396 /* add an elf symbol : check if it is already defined and patch
6397 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6398 static int add_elf_sym(unsigned long value, unsigned long size,
6399 int info, int sh_num, const char *name)
6401 Elf32_Sym *esym;
6402 int sym_bind, sym_index, sym_type, esym_bind;
6404 sym_bind = ELF32_ST_BIND(info);
6405 sym_type = ELF32_ST_TYPE(info);
6407 if (sym_bind != STB_LOCAL) {
6408 /* we search global or weak symbols */
6409 sym_index = find_elf_sym(symtab_section, name);
6410 if (!sym_index)
6411 goto do_def;
6412 esym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6413 if (esym->st_shndx != SHN_UNDEF) {
6414 esym_bind = ELF32_ST_BIND(esym->st_info);
6415 if (sh_num == SHN_UNDEF) {
6416 /* ignore adding of undefined symbol if the
6417 corresponding symbol is already defined */
6418 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
6419 /* global overrides weak, so patch */
6420 goto do_patch;
6421 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
6422 /* weak is ignored if already global */
6423 } else {
6424 #if 0
6425 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6426 sym_bind, sh_num, esym_bind, esym->st_shndx);
6427 #endif
6428 error("'%s' defined twice", name);
6430 } else {
6431 do_patch:
6432 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
6433 esym->st_shndx = sh_num;
6434 esym->st_value = value;
6435 esym->st_size = size;
6437 } else {
6438 do_def:
6439 sym_index = put_elf_sym(symtab_section, value, size,
6440 ELF32_ST_INFO(sym_bind, sym_type), 0,
6441 sh_num, name);
6443 return sym_index;
6446 /* update sym->c so that it points to an external symbol in section
6447 'section' with value 'value' */
6448 void put_extern_sym(Sym *sym, Section *section, unsigned long value)
6450 int sym_type, sym_bind, sh_num, info;
6451 Elf32_Sym *esym;
6452 const char *name;
6454 if (section)
6455 sh_num = section->sh_num;
6456 else
6457 sh_num = SHN_UNDEF;
6458 if (!sym->c) {
6459 if ((sym->t & VT_BTYPE) == VT_FUNC)
6460 sym_type = STT_FUNC;
6461 else
6462 sym_type = STT_OBJECT;
6463 if (sym->t & VT_STATIC)
6464 sym_bind = STB_LOCAL;
6465 else
6466 sym_bind = STB_GLOBAL;
6467 name = get_tok_str(sym->v, NULL);
6468 info = ELF32_ST_INFO(sym_bind, sym_type);
6469 sym->c = add_elf_sym(value, 0, info, sh_num, name);
6470 } else {
6471 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6472 esym->st_value = value;
6473 esym->st_shndx = sh_num;
6477 /* put relocation */
6478 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
6479 int type, int symbol)
6481 char buf[256];
6482 Section *sr;
6483 Elf32_Rel *rel;
6485 sr = s->reloc;
6486 if (!sr) {
6487 /* if no relocation section, create it */
6488 snprintf(buf, sizeof(buf), ".rel%s", s->name);
6489 /* if the symtab is allocated, then we consider the relocation
6490 are also */
6491 sr = new_section(buf, SHT_REL, symtab->sh_flags);
6492 sr->sh_entsize = sizeof(Elf32_Rel);
6493 sr->link = symtab;
6494 sr->sh_info = s->sh_num;
6495 s->reloc = sr;
6497 rel = (Elf32_Rel *)sr->data_ptr;
6498 /* XXX: endianness */
6499 rel->r_offset = offset;
6500 rel->r_info = ELF32_R_INFO(symbol, type);
6501 sr->data_ptr += sizeof(Elf32_Rel);
6504 /* put stab debug information */
6506 typedef struct {
6507 unsigned long n_strx; /* index into string table of name */
6508 unsigned char n_type; /* type of symbol */
6509 unsigned char n_other; /* misc info (usually empty) */
6510 unsigned short n_desc; /* description field */
6511 unsigned long n_value; /* value of symbol */
6512 } Stab_Sym;
6514 static void put_stabs(const char *str, int type, int other, int desc, int value)
6516 Stab_Sym *sym;
6518 sym = (Stab_Sym *)stab_section->data_ptr;
6519 if (str) {
6520 sym->n_strx = put_elf_str(stabstr_section, str);
6521 } else {
6522 sym->n_strx = 0;
6524 sym->n_type = type;
6525 sym->n_other = other;
6526 sym->n_desc = desc;
6527 sym->n_value = value;
6529 stab_section->data_ptr += sizeof(Stab_Sym);
6532 static void put_stabn(int type, int other, int desc, int value)
6534 put_stabs(NULL, type, other, desc, value);
6537 static void put_stabd(int type, int other, int desc)
6539 put_stabs(NULL, type, other, desc, 0);
6542 /* In an ELF file symbol table, the local symbols must appear below
6543 the global and weak ones. Since TCC cannot sort it while generating
6544 the code, we must do it after. All the relocation tables are also
6545 modified to take into account the symbol table sorting */
6546 static void sort_syms(Section *s)
6548 int *old_to_new_syms;
6549 Elf32_Sym *new_syms;
6550 int nb_syms, i;
6551 Elf32_Sym *p, *q;
6552 Elf32_Rel *rel;
6553 Section *sr;
6554 int type, sym_index;
6556 nb_syms = (s->data_ptr - s->data) / sizeof(Elf32_Sym);
6557 new_syms = malloc(nb_syms * sizeof(Elf32_Sym));
6558 if (!new_syms)
6559 error("memory full");
6560 old_to_new_syms = malloc(nb_syms * sizeof(int));
6561 if (!old_to_new_syms)
6562 error("memory full");
6563 /* first pass for local symbols */
6564 p = (Elf32_Sym *)s->data;
6565 q = new_syms;
6566 for(i = 0; i < nb_syms; i++) {
6567 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
6568 old_to_new_syms[i] = q - new_syms;
6569 *q++ = *p;
6571 p++;
6573 /* save the number of local symbols in section header */
6574 s->sh_info = q - new_syms;
6576 /* then second pass for non local symbols */
6577 p = (Elf32_Sym *)s->data;
6578 for(i = 0; i < nb_syms; i++) {
6579 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
6580 old_to_new_syms[i] = q - new_syms;
6581 *q++ = *p;
6583 p++;
6586 /* we copy the new symbols to the old */
6587 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
6588 free(new_syms);
6590 /* now we modify all the relocations */
6591 for(sr = first_section; sr != NULL; sr = sr->next) {
6592 if (sr->sh_type == SHT_REL && sr->link == s) {
6593 for(rel = (Elf32_Rel *)sr->data;
6594 rel < (Elf32_Rel *)sr->data_ptr;
6595 rel++) {
6596 sym_index = ELF32_R_SYM(rel->r_info);
6597 type = ELF32_R_TYPE(rel->r_info);
6598 sym_index = old_to_new_syms[sym_index];
6599 rel->r_info = ELF32_R_INFO(sym_index, type);
6604 free(old_to_new_syms);
6607 /* relocate common symbols in the .bss section */
6608 static void relocate_common_syms(void)
6610 Elf32_Sym *sym;
6611 unsigned long offset, align;
6613 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6614 sym < (Elf32_Sym *)symtab_section->data_ptr;
6615 sym++) {
6616 if (sym->st_shndx == SHN_COMMON) {
6617 /* align symbol */
6618 align = sym->st_value;
6619 offset = bss_section->data_ptr - bss_section->data;
6620 offset = (offset + align - 1) & -align;
6621 sym->st_value = offset;
6622 sym->st_shndx = bss_section->sh_num;
6623 offset += sym->st_size;
6624 bss_section->data_ptr = bss_section->data + offset;
6629 static void *resolve_sym(const char *sym)
6631 #ifdef CONFIG_TCC_BCHECK
6632 if (do_bounds_check) {
6633 void *ptr;
6634 ptr = bound_resolve_sym(sym);
6635 if (ptr)
6636 return ptr;
6638 #endif
6639 return dlsym(NULL, sym);
6642 /* relocate symbol table, resolve undefined symbols if do_resolve is
6643 true and output error if undefined symbol. */
6644 static void relocate_syms(int do_resolve)
6646 Elf32_Sym *sym;
6647 int sym_bind, sh_num;
6648 const char *name;
6649 unsigned long addr;
6651 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6652 sym < (Elf32_Sym *)symtab_section->data_ptr;
6653 sym++) {
6654 sh_num = sym->st_shndx;
6655 if (sh_num == SHN_UNDEF) {
6656 name = strtab_section->data + sym->st_name;
6657 if (do_resolve) {
6658 name = symtab_section->link->data + sym->st_name;
6659 addr = (unsigned long)resolve_sym(name);
6660 if (addr) {
6661 sym->st_value = addr;
6662 goto found;
6665 /* only weak symbols are accepted to be undefined. Their value is zero */
6666 sym_bind = ELF32_ST_BIND(sym->st_info);
6667 if (sym_bind == STB_WEAK) {
6668 sym->st_value = 0;
6669 } else {
6670 // error("undefined symbol '%s'", name);
6671 warning("undefined symbol '%s'", name);
6673 } else if (sh_num < SHN_LORESERVE) {
6674 /* add section base */
6675 sym->st_value += sections[sym->st_shndx]->sh_addr;
6677 found: ;
6681 /* relocate a given section */
6682 static void relocate_section(Section *s)
6684 Section *sr;
6685 Elf32_Rel *rel;
6686 Elf32_Sym *sym;
6687 int type;
6688 unsigned char *ptr;
6689 unsigned long val;
6691 sr = s->reloc;
6692 for(rel = (Elf32_Rel *)sr->data;
6693 rel < (Elf32_Rel *)sr->data_ptr;
6694 rel++) {
6695 ptr = s->data + rel->r_offset;
6697 sym = &((Elf32_Sym *)symtab_section->data)[ELF32_R_SYM(rel->r_info)];
6698 val = sym->st_value;
6699 type = ELF32_R_TYPE(rel->r_info);
6700 greloc_patch(ptr, s->sh_addr + rel->r_offset, val, type);
6704 static Section *new_section_hash(const char *name, int sh_flags,
6705 int nb_buckets, Section *symtab)
6707 Section *hash;
6708 hash = new_section(name, SHT_HASH, sh_flags);
6709 ((int *)hash->data)[0] = nb_buckets;
6710 ((int *)hash->data)[1] = 1;
6711 hash->sh_entsize = sizeof(int);
6712 hash->data_ptr += (2 + nb_buckets + 1) * sizeof(int);
6713 symtab->hash = hash;
6714 hash->link = symtab;
6715 return hash;
6718 /* put dynamic tag */
6719 static void put_dt(Section *dynamic, int dt, unsigned long val)
6721 Elf32_Dyn *dyn;
6722 dyn = (Elf32_Dyn *)dynamic->data_ptr;
6723 dyn->d_tag = dt;
6724 dyn->d_un.d_val = val;
6725 dynamic->data_ptr += sizeof(Elf32_Dyn);
6728 /* add dynamic sections so that the executable is dynamically linked */
6729 static char elf_interp[] = "/lib/ld-linux.so.2";
6731 #define ELF_START_ADDR 0x08048000
6732 #define ELF_PAGE_SIZE 0x1000
6734 /* XXX: suppress that */
6735 static void put32(unsigned char *p, unsigned int val)
6737 p[0] = val;
6738 p[1] = val >> 8;
6739 p[2] = val >> 16;
6740 p[3] = val >> 24;
6743 /* output an ELF file (currently, only for testing) */
6744 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6745 /* XXX: suppress unneeded sections */
6746 int tcc_output_file(TCCState *s1, const char *filename, int file_type)
6748 Elf32_Ehdr ehdr;
6749 FILE *f;
6750 int fd, mode;
6751 int *section_order;
6752 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index;
6753 unsigned long addr;
6754 Section *strsec, *s;
6755 Elf32_Shdr shdr, *sh;
6756 Elf32_Phdr *phdr, *ph;
6757 Section *interp, *plt, *got, *dynamic, *dynsym, *dynstr, *hash;
6758 unsigned char *saved_dynamic_data_ptr;
6759 Elf32_Sym *sym;
6760 int type;
6762 interp = NULL;
6763 dynamic = NULL;
6764 plt = NULL; /* avoid warning */
6765 got = NULL; /* avoid warning */
6766 dynsym = NULL; /* avoid warning */
6767 hash = NULL; /* avoid warning */
6768 dynstr = NULL; /* avoid warning */
6769 saved_dynamic_data_ptr = NULL; /* avoid warning */
6771 if (file_type != TCC_FILE_OBJ) {
6773 relocate_common_syms();
6775 /* a got is needed even if static link for the symbol
6776 _GLOBAL_OFFSET_TABLE_ */
6777 got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6778 got->sh_entsize = 4;
6779 add_elf_sym(0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
6780 got->sh_num, "_GLOBAL_OFFSET_TABLE_");
6781 /* keep space for _DYNAMIC pointer, if present */
6782 got->data_ptr += 4;
6784 if (!static_link) {
6785 const char *name;
6786 int nb_plt_entries;
6788 if (file_type == TCC_FILE_EXE) {
6789 /* add interpreter section only if executable */
6790 interp = new_section(".interp", SHT_PROGBITS, SHF_ALLOC);
6791 interp->sh_addralign = 1;
6792 strcpy(interp->data_ptr, elf_interp);
6793 interp->data_ptr += sizeof(elf_interp);
6796 /* add dynamic symbol table */
6797 dynsym = new_section(".dynsym", SHT_DYNSYM, SHF_ALLOC);
6798 dynsym->sh_entsize = sizeof(Elf32_Sym);
6799 dynstr = new_section(".dynstr", SHT_STRTAB, SHF_ALLOC);
6800 put_elf_str(dynstr, "");
6801 dynsym->link = dynstr;
6802 put_elf_sym(dynsym, 0, 0, 0, 0, 0, NULL);
6804 /* hash table */
6805 hash = new_section_hash(".hash", SHF_ALLOC,
6806 ELF_DYNSYM_HASH_SIZE, dynsym);
6808 /* add dynamic section */
6809 dynamic = new_section(".dynamic", SHT_DYNAMIC,
6810 SHF_ALLOC | SHF_WRITE);
6811 dynamic->link = dynstr;
6812 dynamic->sh_entsize = sizeof(Elf32_Dyn);
6814 /* add PLT and GOT */
6815 plt = new_section(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
6816 plt->sh_entsize = 4;
6818 /* add undefined symbols in dynamic symbol table */
6819 nb_plt_entries = 0;
6820 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6821 sym < (Elf32_Sym *)symtab_section->data_ptr;
6822 sym++) {
6823 if (sym->st_shndx == SHN_UNDEF) {
6824 name = symtab_section->link->data + sym->st_name;
6825 type = ELF32_ST_TYPE(sym->st_info);
6826 put_elf_sym(dynsym, 0, 0,
6827 sym->st_info, 0, SHN_UNDEF, name);
6828 if (type == STT_FUNC) {
6829 nb_plt_entries++;
6830 /* prepare space for relocation */
6831 put_elf_reloc(dynsym, got, 0, 0, 0);
6836 /* update PLT/GOT sizes so that we can allocate their space */
6837 plt->data_ptr += 16 * (nb_plt_entries + 1);
6838 got->data_ptr += 4 * (nb_plt_entries + 2);
6840 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, "libc.so.6"));
6841 /* XXX: add other libs */
6843 /* add necessary space for other entries */
6844 saved_dynamic_data_ptr = dynamic->data_ptr;
6845 dynamic->data_ptr += 8 * 9;
6849 memset(&ehdr, 0, sizeof(ehdr));
6851 /* we add a section for symbols */
6852 strsec = new_section(".shstrtab", SHT_STRTAB, 0);
6853 put_elf_str(strsec, "");
6855 /* compute number of sections */
6856 shnum = nb_sections;
6858 /* this array is used to reorder sections in the output file */
6859 section_order = malloc(sizeof(int) * shnum);
6860 if (!section_order)
6861 error("memory full");
6862 section_order[0] = 0;
6863 sh_order_index = 1;
6865 /* compute number of program headers */
6866 switch(file_type) {
6867 default:
6868 case TCC_FILE_OBJ:
6869 phnum = 0;
6870 break;
6871 case TCC_FILE_EXE:
6872 if (!static_link)
6873 phnum = 4;
6874 else
6875 phnum = 2;
6876 break;
6877 case TCC_FILE_DLL:
6878 phnum = 3;
6879 break;
6882 /* allocate strings for section names */
6883 for(i = 1; i < nb_sections; i++) {
6884 s = sections[i];
6885 s->sh_name = put_elf_str(strsec, s->name);
6886 s->sh_size = s->data_ptr - s->data;
6889 /* allocate program segment headers */
6890 phdr = malloc(phnum * sizeof(Elf32_Phdr));
6891 if (!phdr)
6892 error("memory full");
6893 memset(phdr, 0, phnum * sizeof(Elf32_Phdr));
6895 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
6896 if (phnum > 0) {
6897 /* compute section to program header mapping */
6898 if (file_type == TCC_FILE_DLL)
6899 addr = 0;
6900 else
6901 addr = ELF_START_ADDR;
6903 /* compute address after headers */
6904 addr += (file_offset & (ELF_PAGE_SIZE - 1));
6906 /* leave one program header for the program interpreter */
6907 ph = &phdr[0];
6908 if (interp)
6909 ph++;
6911 for(j = 0; j < 2; j++) {
6912 ph->p_type = PT_LOAD;
6913 if (j == 0)
6914 ph->p_flags = PF_R | PF_X;
6915 else
6916 ph->p_flags = PF_R | PF_W;
6917 ph->p_align = ELF_PAGE_SIZE;
6919 for(i = 1; i < nb_sections; i++) {
6920 s = sections[i];
6921 /* compute if section should be included */
6922 if (j == 0) {
6923 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
6924 SHF_ALLOC)
6925 continue;
6926 } else {
6927 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
6928 (SHF_ALLOC | SHF_WRITE))
6929 continue;
6931 section_order[sh_order_index++] = i;
6933 /* section matches: we align it and add its size */
6934 tmp = file_offset;
6935 file_offset = (file_offset + s->sh_addralign - 1) &
6936 ~(s->sh_addralign - 1);
6937 s->sh_offset = file_offset;
6938 addr += file_offset - tmp;
6939 s->sh_addr = addr;
6941 if (ph->p_offset == 0) {
6942 ph->p_offset = file_offset;
6943 ph->p_vaddr = addr;
6944 ph->p_paddr = ph->p_vaddr;
6946 addr += s->sh_size;
6947 if (s->sh_type != SHT_NOBITS)
6948 file_offset += s->sh_size;
6950 ph->p_filesz = file_offset - ph->p_offset;
6951 ph->p_memsz = addr - ph->p_vaddr;
6952 ph++;
6955 /* if interpreter, then add corresponing program header */
6956 if (interp) {
6957 ph = &phdr[0];
6959 ph->p_type = PT_INTERP;
6960 ph->p_offset = interp->sh_offset;
6961 ph->p_vaddr = interp->sh_addr;
6962 ph->p_paddr = ph->p_vaddr;
6963 ph->p_filesz = interp->sh_size;
6964 ph->p_memsz = interp->sh_size;
6965 ph->p_flags = PF_R;
6966 ph->p_align = interp->sh_addralign;
6969 /* if dynamic section, then add corresponing program header */
6970 if (dynamic) {
6971 int sym_index, plt_offset;
6972 unsigned char *p;
6974 ph = &phdr[phnum - 1];
6976 ph->p_type = PT_DYNAMIC;
6977 ph->p_offset = dynamic->sh_offset;
6978 ph->p_vaddr = dynamic->sh_addr;
6979 ph->p_paddr = ph->p_vaddr;
6980 ph->p_filesz = dynamic->sh_size;
6981 ph->p_memsz = dynamic->sh_size;
6982 ph->p_flags = PF_R | PF_W;
6983 ph->p_align = dynamic->sh_addralign;
6985 /* now all the sections are mapped, so we can compute all
6986 PLT/GOT stuff */
6988 /* first three got entries */
6989 got->data_ptr = got->data;
6990 plt->data_ptr = plt->data;
6991 if (got->reloc)
6992 got->reloc->data_ptr = got->reloc->data;
6994 put32(got->data_ptr, dynamic->sh_addr);
6995 got->data_ptr += 4;
6996 put32(got->data_ptr, 0);
6997 got->data_ptr += 4;
6998 put32(got->data_ptr, 0);
6999 got->data_ptr += 4;
7001 /* first plt entry */
7002 p = plt->data_ptr;
7003 p[0] = 0xff; /* pushl got + 4 */
7004 p[1] = 0x35;
7005 put32(p + 2, got->sh_addr + 4);
7006 p[6] = 0xff; /* jmp *(got + 8) */
7007 p[7] = 0x25;
7008 put32(p + 8, got->sh_addr + 8);
7009 plt->data_ptr += 16;
7011 /* add undefined symbols in dynamic symbol table. also update
7012 PLT and GOT if needed */
7013 plt_offset = 0;
7014 sym_index = 1;
7015 for(sym = (Elf32_Sym *)dynsym->data + 1;
7016 sym < (Elf32_Sym *)dynsym->data_ptr;
7017 sym++) {
7018 type = ELF32_ST_TYPE(sym->st_info);
7019 if (type == STT_FUNC) {
7020 /* one more entry in PLT */
7021 p = plt->data_ptr;
7022 p[0] = 0xff; /* jmp *(got + x) */
7023 p[1] = 0x25;
7024 put32(p + 2, got->sh_addr + got->data_ptr - got->data);
7025 p[6] = 0x68; /* push $xxx */
7026 put32(p + 7, plt_offset);
7027 p[11] = 0xe9; /* jmp plt_start */
7028 put32(p + 12, -(plt->data_ptr + 16 - plt->data));
7030 /* patch symbol value to point to plt */
7031 sym->st_value = plt->sh_addr + p - plt->data;
7033 plt_offset += 8;
7034 plt->data_ptr += 16;
7036 /* corresponding got entry */
7037 put_elf_reloc(dynsym, got,
7038 got->sh_addr + got->data_ptr - got->data,
7039 R_386_JMP_SLOT,
7040 sym_index);
7041 put32(got->data_ptr, 0);
7042 got->data_ptr += 4;
7044 sym_index++;
7046 /* put dynamic section entries */
7048 dynamic->data_ptr = saved_dynamic_data_ptr;
7049 put_dt(dynamic, DT_HASH, hash->sh_addr);
7050 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
7051 put_dt(dynamic, DT_SYMTAB, dynsym->sh_addr);
7052 put_dt(dynamic, DT_STRSZ, dynstr->data_ptr - dynstr->data);
7053 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
7054 put_dt(dynamic, DT_REL, got->reloc->sh_addr);
7055 put_dt(dynamic, DT_RELSZ, got->reloc->data_ptr - got->reloc->data);
7056 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
7057 put_dt(dynamic, DT_NULL, 0);
7060 ehdr.e_phentsize = sizeof(Elf32_Phdr);
7061 ehdr.e_phnum = phnum;
7062 ehdr.e_phoff = sizeof(Elf32_Ehdr);
7065 /* all other sections come after */
7066 for(i = 1; i < nb_sections; i++) {
7067 s = sections[i];
7068 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
7069 continue;
7070 section_order[sh_order_index++] = i;
7072 file_offset = (file_offset + s->sh_addralign - 1) &
7073 ~(s->sh_addralign - 1);
7074 s->sh_offset = file_offset;
7075 if (s->sh_type != SHT_NOBITS)
7076 file_offset += s->sh_size;
7079 /* if building executable or DLL, then relocate each section
7080 except the GOT which is already relocated */
7081 if (file_type != TCC_FILE_OBJ) {
7082 relocate_syms(0);
7084 for(i = 1; i < nb_sections; i++) {
7085 s = sections[i];
7086 if (s->reloc && s != got)
7087 relocate_section(s);
7090 /* get entry point address */
7091 ehdr.e_entry = get_elf_sym_val("_start");
7094 sort_syms(symtab_section);
7096 /* align to 4 */
7097 file_offset = (file_offset + 3) & -4;
7099 /* fill header */
7100 ehdr.e_ident[0] = ELFMAG0;
7101 ehdr.e_ident[1] = ELFMAG1;
7102 ehdr.e_ident[2] = ELFMAG2;
7103 ehdr.e_ident[3] = ELFMAG3;
7104 ehdr.e_ident[4] = ELFCLASS32;
7105 ehdr.e_ident[5] = ELFDATA2LSB;
7106 ehdr.e_ident[6] = EV_CURRENT;
7107 switch(file_type) {
7108 default:
7109 case TCC_FILE_EXE:
7110 ehdr.e_type = ET_EXEC;
7111 break;
7112 case TCC_FILE_DLL:
7113 ehdr.e_type = ET_DYN;
7114 break;
7115 case TCC_FILE_OBJ:
7116 ehdr.e_type = ET_REL;
7117 break;
7119 ehdr.e_machine = EM_386;
7120 ehdr.e_version = EV_CURRENT;
7121 ehdr.e_shoff = file_offset;
7122 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
7123 ehdr.e_shentsize = sizeof(Elf32_Shdr);
7124 ehdr.e_shnum = shnum;
7125 ehdr.e_shstrndx = shnum - 1;
7127 /* write elf file */
7128 if (file_type == TCC_FILE_OBJ)
7129 mode = 0666;
7130 else
7131 mode = 0777;
7132 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
7133 if (fd < 0)
7134 error("could not write '%s'", filename);
7136 f = fdopen(fd, "w");
7137 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
7138 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
7139 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
7140 for(i=1;i<nb_sections;i++) {
7141 s = sections[section_order[i]];
7142 if (s->sh_type != SHT_NOBITS) {
7143 while (offset < s->sh_offset) {
7144 fputc(0, f);
7145 offset++;
7147 size = s->data_ptr - s->data;
7148 fwrite(s->data, 1, size, f);
7149 offset += size;
7152 while (offset < ehdr.e_shoff) {
7153 fputc(0, f);
7154 offset++;
7157 /* output section headers */
7158 for(i=0;i<nb_sections;i++) {
7159 sh = &shdr;
7160 memset(sh, 0, sizeof(Elf32_Shdr));
7161 s = sections[i];
7162 if (s) {
7163 sh->sh_name = s->sh_name;
7164 sh->sh_type = s->sh_type;
7165 sh->sh_flags = s->sh_flags;
7166 sh->sh_entsize = s->sh_entsize;
7167 sh->sh_info = s->sh_info;
7168 if (s->link)
7169 sh->sh_link = s->link->sh_num;
7170 sh->sh_addralign = s->sh_addralign;
7171 sh->sh_addr = s->sh_addr;
7172 sh->sh_offset = s->sh_offset;
7173 sh->sh_size = s->sh_size;
7175 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
7177 fclose(f);
7179 free(section_order);
7180 free(phdr);
7181 return 0;
7184 typedef struct SectionMergeInfo {
7185 Section *s; /* corresponding existing section */
7186 unsigned long offset; /* offset of the new section in the existing section */
7187 int new_section; /* true if section 's' was added */
7188 } SectionMergeInfo;
7190 /* load an object file and merge it with current files */
7191 /* XXX: handle correctly stab (debug) info */
7192 static int tcc_load_object_file(TCCState *s1,
7193 const char *filename,
7194 FILE *f, unsigned long file_offset)
7196 Elf32_Ehdr ehdr;
7197 Elf32_Shdr *shdr, *sh;
7198 int size, i, j, offset, offseti, nb_syms, sym_index;
7199 unsigned char *strsec, *strtab;
7200 int *old_to_new_syms;
7201 char *sh_name, *name;
7202 SectionMergeInfo *sm_table, *sm;
7203 Elf32_Sym *sym, *symtab;
7204 Elf32_Rel *rel;
7205 Section *s;
7207 if (fread(&ehdr, 1, sizeof(ehdr), f) != sizeof(ehdr))
7208 goto fail;
7209 if (ehdr.e_ident[0] != ELFMAG0 ||
7210 ehdr.e_ident[1] != ELFMAG1 ||
7211 ehdr.e_ident[2] != ELFMAG2 ||
7212 ehdr.e_ident[3] != ELFMAG3)
7213 goto fail;
7214 /* test if object file */
7215 if (ehdr.e_type != ET_REL)
7216 goto fail;
7217 /* test CPU specific stuff */
7218 if (ehdr.e_ident[5] != ELFDATA2LSB ||
7219 ehdr.e_machine != EM_386) {
7220 fail:
7221 error("invalid object file '%s'", filename);
7223 /* read sections */
7224 size = sizeof(Elf32_Shdr) * ehdr.e_shnum;
7225 shdr = malloc(size);
7226 if (!shdr)
7227 error("memory full");
7228 fseek(f, file_offset + ehdr.e_shoff, SEEK_SET);
7229 if (fread(shdr, 1, size, f) != size)
7230 goto fail;
7232 sm_table = malloc(sizeof(SectionMergeInfo) * ehdr.e_shnum);
7233 if (!sm_table)
7234 error("memory full");
7235 memset(sm_table, 0, sizeof(SectionMergeInfo) * ehdr.e_shnum);
7237 /* load section names */
7238 sh = &shdr[ehdr.e_shstrndx];
7239 strsec = malloc(sh->sh_size);
7240 if (!strsec)
7241 error("memory full");
7242 fseek(f, file_offset + sh->sh_offset, SEEK_SET);
7243 fread(strsec, 1, sh->sh_size, f);
7245 /* load symtab and strtab */
7246 symtab = NULL;
7247 strtab = NULL;
7248 nb_syms = 0;
7249 for(i = 1; i < ehdr.e_shnum; i++) {
7250 sh = &shdr[i];
7251 if (sh->sh_type == SHT_SYMTAB) {
7252 if (symtab)
7253 error("object must contain only one symtab");
7254 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
7255 symtab = malloc(sh->sh_size);
7256 if (!symtab)
7257 error("memory full");
7258 fseek(f, file_offset + sh->sh_offset, SEEK_SET);
7259 fread(symtab, 1, sh->sh_size, f);
7260 sm_table[i].s = symtab_section;
7262 /* now load strtab */
7263 sh = &shdr[sh->sh_link];
7264 strtab = malloc(sh->sh_size);
7265 if (!strtab)
7266 error("memory full");
7267 fseek(f, file_offset + sh->sh_offset, SEEK_SET);
7268 fread(strtab, 1, sh->sh_size, f);
7272 /* now examine each section and try to merge its content with the
7273 ones in memory */
7274 for(i = 1; i < ehdr.e_shnum; i++) {
7275 /* no need to examine section name strtab */
7276 if (i == ehdr.e_shstrndx)
7277 continue;
7278 sh = &shdr[i];
7279 sh_name = strsec + sh->sh_name;
7280 /* ignore sections types we do not handle */
7281 if (sh->sh_type != SHT_PROGBITS &&
7282 sh->sh_type != SHT_REL &&
7283 sh->sh_type != SHT_NOBITS)
7284 continue;
7285 if (sh->sh_addralign < 1)
7286 sh->sh_addralign = 1;
7287 /* find corresponding section, if any */
7288 for(j = 1; j < nb_sections;j++) {
7289 s = sections[j];
7290 if (!strcmp(s->name, sh_name))
7291 goto found;
7293 /* not found: create new section */
7294 s = new_section(sh_name, sh->sh_type, sh->sh_flags);
7295 /* take as much info as possible from the section. sh_link and
7296 sh_info will be updated later */
7297 s->sh_addralign = sh->sh_addralign;
7298 s->sh_entsize = sh->sh_entsize;
7299 sm_table[i].new_section = 1;
7300 found:
7301 if (sh->sh_type != s->sh_type)
7302 goto fail;
7304 /* align start of section */
7305 offset = s->data_ptr - s->data;
7306 size = sh->sh_addralign - 1;
7307 offset = (offset + size) & ~size;
7308 if (sh->sh_addralign > s->sh_addralign)
7309 s->sh_addralign = sh->sh_addralign;
7310 s->data_ptr = s->data + offset;
7311 sm_table[i].offset = offset;
7312 sm_table[i].s = s;
7313 /* concatenate sections */
7314 size = sh->sh_size;
7315 if (sh->sh_type != SHT_NOBITS) {
7316 fseek(f, file_offset + sh->sh_offset, SEEK_SET);
7317 fread(s->data_ptr, 1, size, f);
7319 s->data_ptr += size;
7322 /* second short pass to update sh_link and sh_info fields of new
7323 sections */
7324 sm = sm_table;
7325 for(i = 1; i < ehdr.e_shnum; i++) {
7326 s = sm_table[i].s;
7327 if (!s || !sm_table[i].new_section)
7328 continue;
7329 sh = &shdr[i];
7330 if (sh->sh_link > 0)
7331 s->link = sm_table[sh->sh_link].s;
7332 if (sh->sh_type == SHT_REL) {
7333 s->sh_info = sm_table[sh->sh_info].s->sh_num;
7334 /* update backward link */
7335 sections[s->sh_info]->reloc = s;
7339 /* resolve symbols */
7340 old_to_new_syms = malloc(nb_syms * sizeof(int));
7341 if (!old_to_new_syms)
7342 error("memory full");
7343 memset(old_to_new_syms, 0, nb_syms * sizeof(int));
7344 sym = symtab + 1;
7345 for(i = 1; i < nb_syms; i++, sym++) {
7346 if (sym->st_shndx != SHN_UNDEF &&
7347 sym->st_shndx < SHN_LORESERVE) {
7348 sm = &sm_table[sym->st_shndx];
7349 /* if no corresponding section added, no need to add symbol */
7350 if (!sm->s)
7351 continue;
7352 /* convert section number */
7353 sym->st_shndx = sm->s->sh_num;
7354 /* offset value */
7355 sym->st_value += sm->offset;
7357 /* add symbol */
7358 name = strtab + sym->st_name;
7359 sym_index = add_elf_sym(sym->st_value, sym->st_size,
7360 sym->st_info, sym->st_shndx, name);
7361 old_to_new_syms[i] = sym_index;
7364 /* third pass to patch relocation entries */
7365 for(i = 1; i < ehdr.e_shnum; i++) {
7366 s = sm_table[i].s;
7367 if (!s)
7368 continue;
7369 sh = &shdr[i];
7370 offset = sm_table[i].offset;
7371 switch(s->sh_type) {
7372 case SHT_REL:
7373 /* take relocation offset information */
7374 offseti = sm_table[sh->sh_info].offset;
7375 for(rel = (Elf32_Rel *)(s->data + offset);
7376 rel < (Elf32_Rel *)s->data_ptr;
7377 rel++) {
7378 int type;
7379 unsigned sym_index;
7380 /* convert symbol index */
7381 type = ELF32_R_TYPE(rel->r_info);
7382 sym_index = ELF32_R_SYM(rel->r_info);
7383 /* NOTE: only one symtab assumed */
7384 if (sym_index >= nb_syms)
7385 goto invalid_reloc;
7386 sym_index = old_to_new_syms[sym_index];
7387 if (!sym_index) {
7388 invalid_reloc:
7389 error("Invalid relocation entry");
7391 rel->r_info = ELF32_R_INFO(sym_index, type);
7392 /* offset the relocation offset */
7393 rel->r_offset += offseti;
7395 break;
7396 default:
7397 break;
7400 free(symtab);
7401 free(strtab);
7402 free(old_to_new_syms);
7403 free(sm_table);
7404 free(shdr);
7405 return 0;
7408 int tcc_load_object(TCCState *s1, const char *filename)
7410 FILE *f;
7411 int ret;
7413 f = fopen(filename, "r");
7414 if (!f)
7415 error("could not open '%s'", filename);
7416 ret = tcc_load_object_file(s1, filename, f, 0);
7417 fclose(f);
7418 return ret;
7421 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7423 typedef struct ArchiveHeader {
7424 char ar_name[16]; /* name of this member */
7425 char ar_date[12]; /* file mtime */
7426 char ar_uid[6]; /* owner uid; printed as decimal */
7427 char ar_gid[6]; /* owner gid; printed as decimal */
7428 char ar_mode[8]; /* file mode, printed as octal */
7429 char ar_size[10]; /* file size, printed as decimal */
7430 char ar_fmag[2]; /* should contain ARFMAG */
7431 } ArchiveHeader;
7433 /* load a '.a' file */
7434 int tcc_load_archive(TCCState *s1, const char *filename)
7436 ArchiveHeader hdr;
7437 char magic[8];
7438 char ar_size[11];
7439 char ar_name[17];
7440 int size, len, i;
7441 FILE *f;
7442 unsigned long file_offset;
7444 f = fopen(filename, "r");
7445 if (!f)
7446 error("could not open '%s'", filename);
7447 len = fread(magic, 1, sizeof(magic), f);
7448 if (len != sizeof(magic) ||
7449 memcmp(magic, ARMAG, sizeof(magic)) != 0)
7450 error("invalid archive magic");
7452 for(;;) {
7453 len = fread(&hdr, 1, sizeof(hdr), f);
7454 if (len == 0)
7455 break;
7456 if (len != sizeof(hdr))
7457 error("invalid archive");
7458 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
7459 ar_size[sizeof(hdr.ar_size)] = '\0';
7460 size = strtol(ar_size, NULL, 0);
7461 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
7462 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
7463 if (ar_name[i] != ' ')
7464 break;
7466 ar_name[i + 1] = '\0';
7467 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7468 file_offset = ftell(f);
7469 if (!strcmp(ar_name, "/") ||
7470 !strcmp(ar_name, "//") ||
7471 !strcmp(ar_name, "__.SYMDEF") ||
7472 !strcmp(ar_name, "__.SYMDEF/") ||
7473 !strcmp(ar_name, "ARFILENAMES/")) {
7474 /* skip symbol table or archive names */
7475 } else {
7476 tcc_load_object_file(s1, filename, f, file_offset);
7478 /* align to even */
7479 size = (size + 1) & ~1;
7480 fseek(f, file_offset + size, SEEK_SET);
7482 fclose(f);
7483 return 0;
7487 /* print the position in the source file of PC value 'pc' by reading
7488 the stabs debug information */
7489 static void rt_printline(unsigned long wanted_pc)
7491 Stab_Sym *sym, *sym_end;
7492 char func_name[128];
7493 unsigned long func_addr, last_pc, pc;
7494 const char *incl_files[INCLUDE_STACK_SIZE];
7495 int incl_index, len, last_line_num, i;
7496 const char *str, *p;
7498 func_name[0] = '\0';
7499 func_addr = 0;
7500 incl_index = 0;
7501 last_pc = 0xffffffff;
7502 last_line_num = 1;
7503 sym = (Stab_Sym *)stab_section->data + 1;
7504 sym_end = (Stab_Sym *)stab_section->data_ptr;
7505 while (sym < sym_end) {
7506 switch(sym->n_type) {
7507 /* function start or end */
7508 case N_FUN:
7509 if (sym->n_strx == 0) {
7510 func_name[0] = '\0';
7511 func_addr = 0;
7512 } else {
7513 str = stabstr_section->data + sym->n_strx;
7514 p = strchr(str, ':');
7515 if (!p) {
7516 pstrcpy(func_name, sizeof(func_name), str);
7517 } else {
7518 len = p - str;
7519 if (len > sizeof(func_name) - 1)
7520 len = sizeof(func_name) - 1;
7521 memcpy(func_name, str, len);
7522 func_name[len] = '\0';
7524 func_addr = sym->n_value;
7526 break;
7527 /* line number info */
7528 case N_SLINE:
7529 pc = sym->n_value + func_addr;
7530 if (wanted_pc >= last_pc && wanted_pc < pc)
7531 goto found;
7532 last_pc = pc;
7533 last_line_num = sym->n_desc;
7534 break;
7535 /* include files */
7536 case N_BINCL:
7537 str = stabstr_section->data + sym->n_strx;
7538 add_incl:
7539 if (incl_index < INCLUDE_STACK_SIZE) {
7540 incl_files[incl_index++] = str;
7542 break;
7543 case N_EINCL:
7544 if (incl_index > 1)
7545 incl_index--;
7546 break;
7547 case N_SO:
7548 if (sym->n_strx == 0) {
7549 incl_index = 0; /* end of translation unit */
7550 } else {
7551 str = stabstr_section->data + sym->n_strx;
7552 /* do not add path */
7553 len = strlen(str);
7554 if (len > 0 && str[len - 1] != '/')
7555 goto add_incl;
7557 break;
7559 sym++;
7561 /* did not find line number info: */
7562 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
7563 return;
7564 found:
7565 for(i = 0; i < incl_index - 1; i++)
7566 fprintf(stderr, "In file included from %s\n",
7567 incl_files[i]);
7568 if (incl_index > 0) {
7569 fprintf(stderr, "%s:%d: ",
7570 incl_files[incl_index - 1], last_line_num);
7572 if (func_name[0] != '\0') {
7573 fprintf(stderr, "in function '%s()': ", func_name);
7577 /* emit a run time error at position 'pc' */
7578 void rt_error(unsigned long pc, const char *fmt, ...)
7580 va_list ap;
7581 va_start(ap, fmt);
7583 rt_printline(pc);
7584 vfprintf(stderr, fmt, ap);
7585 fprintf(stderr, "\n");
7586 exit(255);
7587 va_end(ap);
7590 #ifndef WIN32
7591 /* signal handler for fatal errors */
7592 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7594 struct ucontext *uc = puc;
7595 unsigned long pc;
7597 #ifdef __i386__
7598 pc = uc->uc_mcontext.gregs[14];
7599 #else
7600 #error please put the right sigcontext field
7601 #endif
7603 switch(signum) {
7604 case SIGFPE:
7605 switch(siginf->si_code) {
7606 case FPE_INTDIV:
7607 case FPE_FLTDIV:
7608 rt_error(pc, "division by zero");
7609 break;
7610 default:
7611 rt_error(pc, "floating point exception");
7612 break;
7614 break;
7615 case SIGBUS:
7616 case SIGSEGV:
7617 rt_error(pc, "dereferencing invalid pointer");
7618 break;
7619 case SIGILL:
7620 rt_error(pc, "illegal instruction");
7621 break;
7622 case SIGABRT:
7623 rt_error(pc, "abort() called");
7624 break;
7625 default:
7626 rt_error(pc, "caught signal %d", signum);
7627 break;
7629 exit(255);
7631 #endif
7633 /* launch the compiled program with the given arguments */
7634 int tcc_run(TCCState *s1, int argc, char **argv)
7636 Section *s;
7637 int (*prog_main)(int, char **);
7639 relocate_common_syms();
7641 /* compute relocation address : section are relocated in place */
7642 for(s = first_section; s != NULL; s = s->next) {
7643 if (s->sh_flags & SHF_ALLOC)
7644 s->sh_addr = (unsigned long)s->data;
7647 relocate_syms(1);
7649 /* relocate each section */
7650 for(s = first_section; s != NULL; s = s->next) {
7651 if ((s->sh_flags & SHF_ALLOC) && s->reloc)
7652 relocate_section(s);
7655 prog_main = (void *)get_elf_sym_val("main");
7657 if (do_debug) {
7658 #ifdef WIN32
7659 error("debug mode currently not available for Windows");
7660 #else
7661 struct sigaction sigact;
7662 /* install TCC signal handlers to print debug info on fatal
7663 runtime errors */
7664 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7665 sigact.sa_sigaction = sig_error;
7666 sigemptyset(&sigact.sa_mask);
7667 sigaction(SIGFPE, &sigact, NULL);
7668 sigaction(SIGILL, &sigact, NULL);
7669 sigaction(SIGSEGV, &sigact, NULL);
7670 sigaction(SIGBUS, &sigact, NULL);
7671 sigaction(SIGABRT, &sigact, NULL);
7672 #endif
7675 #ifdef CONFIG_TCC_BCHECK
7676 if (do_bounds_check) {
7677 int *p, *p_end;
7678 __bound_init();
7679 /* add all known static regions */
7680 p = (int *)bounds_section->data;
7681 p_end = (int *)bounds_section->data_ptr;
7682 while (p < p_end) {
7683 __bound_new_region((void *)p[0], p[1]);
7684 p += 2;
7687 #endif
7689 return (*prog_main)(argc, argv);
7692 TCCState *tcc_new(void)
7694 char *p, *r;
7695 TCCState *s;
7697 s = malloc(sizeof(TCCState));
7698 if (!s)
7699 return NULL;
7701 /* default include paths */
7702 nb_include_paths = 0;
7703 tcc_add_include_path(s, "/usr/include");
7704 tcc_add_include_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7706 /* add all tokens */
7707 tok_ident = TOK_IDENT;
7708 p = tcc_keywords;
7709 while (*p) {
7710 r = p;
7711 while (*r++);
7712 tok_alloc(p, r - p - 1);
7713 p = r;
7716 /* standard defines */
7717 tcc_define_symbol(s, "__STDC__", NULL);
7718 #ifdef __i386__
7719 tcc_define_symbol(s, "__i386__", NULL);
7720 #endif
7721 /* tiny C specific defines */
7722 tcc_define_symbol(s, "__TINYC__", NULL);
7724 /* create standard sections */
7725 nb_sections = 1;
7726 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7727 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7728 bss_section = new_section(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
7730 /* symbols are always generated for linking stage */
7731 symtab_section = new_section(".symtab", SHT_SYMTAB, 0);
7732 symtab_section->sh_entsize = sizeof(Elf32_Sym);
7733 strtab_section = new_section(".strtab", SHT_STRTAB, 0);
7734 put_elf_str(strtab_section, "");
7735 symtab_section->link = strtab_section;
7736 put_elf_sym(symtab_section, 0, 0, 0, 0, 0, NULL);
7738 /* private hash table for extern symbols */
7739 new_section_hash(".hashtab", SHF_PRIVATE,
7740 ELF_SYM_HASH_SIZE, symtab_section);
7741 return s;
7744 void tcc_delete(TCCState *s)
7746 free(s);
7749 int tcc_add_include_path(TCCState *s, const char *pathname)
7751 char *pathname1;
7753 if (nb_include_paths >= INCLUDE_PATHS_MAX)
7754 return -1;
7755 pathname1 = strdup(pathname);
7756 if (!pathname1)
7757 return -1;
7758 include_paths[nb_include_paths++] = pathname1;
7759 return 0;
7762 #if !defined(LIBTCC)
7764 void tcc_add_file(TCCState *s, const char *filename)
7766 const char *p;
7767 int ext;
7769 /* find file type with extension */
7770 p = strrchr(filename, '.');
7771 if (!p)
7772 ext = '\0';
7773 else
7774 ext = p[1];
7775 switch(ext) {
7776 case 'o':
7777 tcc_load_object(s, filename);
7778 break;
7779 case 'a':
7780 tcc_load_archive(s, filename);
7781 break;
7782 default:
7783 tcc_compile_file(s, filename);
7784 break;
7788 void help(void)
7790 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7791 "usage: tcc [-c] [-o outfile] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7792 " [-g] [-b] [-llib] [-shared] [-static]\n"
7793 " [--] infile1 [infile2... --] [infile_args...]\n"
7794 "\n"
7795 "General options:\n"
7796 " -c compile only - generate an object file\n"
7797 " -o outfile set output filename (NOT WORKING YET)\n"
7798 " -bench output compilation statistics\n"
7799 " -- allows multiples input files if no -o option given. Also\n"
7800 " separate input files from runtime arguments\n"
7801 "Preprocessor options:\n"
7802 " -Idir add include path 'dir'\n"
7803 " -Dsym[=val] define 'sym' with value 'val'\n"
7804 " -Usym undefine 'sym'\n"
7805 "C compiler options:\n"
7806 " -g generate runtime debug info\n"
7807 #ifdef CONFIG_TCC_BCHECK
7808 " -b compile with built-in memory and bounds checker (implies -g)\n"
7809 #endif
7810 "Linker options:\n"
7811 " -llib link with dynamic library 'lib'\n"
7812 " -shared generate a shared library (NOT WORKING YET)\n"
7813 " -static static linking (NOT WORKING YET)\n"
7817 int main(int argc, char **argv)
7819 char *r, *outfile;
7820 int optind, file_type, multiple_files;
7821 TCCState *s;
7823 s = tcc_new();
7824 file_type = TCC_FILE_EXE;
7826 optind = 1;
7827 outfile = NULL;
7828 multiple_files = 0;
7829 while (1) {
7830 if (optind >= argc) {
7831 show_help:
7832 help();
7833 return 1;
7835 r = argv[optind];
7836 if (r[0] != '-')
7837 break;
7838 optind++;
7839 if (r[1] == '-') {
7840 /* '--' enables multiple files input */
7841 multiple_files = 1;
7842 } else if (r[1] == 'h' || r[1] == '?') {
7843 goto show_help;
7844 } else if (r[1] == 'I') {
7845 if (tcc_add_include_path(s, r + 2) < 0)
7846 error("too many include paths");
7847 } else if (r[1] == 'D') {
7848 char *sym, *value;
7849 sym = r + 2;
7850 value = strchr(sym, '=');
7851 if (value) {
7852 *value = '\0';
7853 value++;
7855 tcc_define_symbol(s, sym, value);
7856 } else if (r[1] == 'U') {
7857 tcc_undefine_symbol(s, r + 2);
7858 } else if (r[1] == 'l') {
7859 char buf[1024];
7860 snprintf(buf, sizeof(buf), "lib%s.so", r + 2);
7861 tcc_add_dll(s, buf);
7862 } else if (!strcmp(r + 1, "bench")) {
7863 do_bench = 1;
7864 #ifdef CONFIG_TCC_BCHECK
7865 } else if (r[1] == 'b') {
7866 if (!do_bounds_check) {
7867 do_bounds_check = 1;
7868 /* define symbol */
7869 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7870 /* create bounds sections */
7871 bounds_section = new_section(".bounds",
7872 SHT_PROGBITS, SHF_ALLOC);
7873 lbounds_section = new_section(".lbounds",
7874 SHT_PROGBITS, SHF_ALLOC);
7875 /* debug is implied */
7876 goto debug_opt;
7878 #endif
7879 } else if (r[1] == 'g') {
7880 #ifdef CONFIG_TCC_BCHECK
7881 debug_opt:
7882 #endif
7883 if (!do_debug) {
7884 do_debug = 1;
7886 /* stab symbols */
7887 stab_section = new_section(".stab", SHT_PROGBITS, 0);
7888 stab_section->sh_entsize = sizeof(Stab_Sym);
7889 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
7890 put_elf_str(stabstr_section, "");
7891 stab_section->link = stabstr_section;
7892 /* put first entry */
7893 put_stabs("", 0, 0, 0, 0);
7895 } else
7896 /* the following options are only for testing, so not
7897 documented */
7898 if (r[1] == 'c') {
7899 multiple_files = 1;
7900 file_type = TCC_FILE_OBJ;
7901 } else if (!strcmp(r + 1, "static")) {
7902 static_link = 1;
7903 } else if (!strcmp(r + 1, "shared")) {
7904 file_type = TCC_FILE_DLL;
7905 } else if (r[1] == 'o') {
7906 if (optind >= argc)
7907 goto show_help;
7908 multiple_files = 1;
7909 outfile = argv[optind++];
7910 } else {
7911 error("invalid option -- '%s'", r);
7915 /* add libc crt1/crti objects */
7916 if (outfile && file_type != TCC_FILE_OBJ) {
7917 if (file_type != TCC_FILE_DLL)
7918 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7919 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7922 tcc_add_file(s, argv[optind]);
7923 if (multiple_files) {
7924 while ((optind + 1) < argc) {
7925 optind++;
7926 r = argv[optind];
7927 if (r[0] == '-') {
7928 if (r[1] != '-')
7929 error("'--' expected");
7930 break;
7932 tcc_add_file(s, r);
7936 /* add libc crtn object */
7937 if (outfile && file_type != TCC_FILE_OBJ) {
7938 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crtn.o");
7941 if (do_bench) {
7942 printf("total: %d idents, %d lines, %d bytes\n",
7943 tok_ident - TOK_IDENT, total_lines, total_bytes);
7946 if (outfile) {
7947 tcc_output_file(s, outfile, file_type);
7948 return 0;
7949 } else {
7950 return tcc_run(s, argc - optind, argv + optind);
7954 #endif