better elf output - fixed float relocation data
[tinycc.git] / tcc.c
blob3a9a7ccd0653c12869b67b741ae602405c320a92
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 /* amount of virtual memory associated to a section (currently, we do
65 not realloc them) */
66 #define SECTION_VSIZE (1024 * 1024)
68 #define INCLUDE_STACK_SIZE 32
69 #define IFDEF_STACK_SIZE 64
70 #define VSTACK_SIZE 64
71 #define STRING_MAX_SIZE 1024
72 #define INCLUDE_PATHS_MAX 32
74 #define TOK_HASH_SIZE 2048 /* must be a power of two */
75 #define TOK_ALLOC_INCR 512 /* must be a power of two */
76 #define SYM_HASH_SIZE 1031
77 #define ELF_SYM_HASH_SIZE 2048
78 #define ELF_DYNSYM_HASH_SIZE 32
80 /* token symbol management */
81 typedef struct TokenSym {
82 struct TokenSym *hash_next;
83 int tok; /* token number */
84 int len;
85 char str[1];
86 } TokenSym;
88 /* constant value */
89 typedef union CValue {
90 long double ld;
91 double d;
92 float f;
93 int i;
94 unsigned int ui;
95 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
96 long long ll;
97 unsigned long long ull;
98 struct TokenSym *ts;
99 struct Sym *sym;
100 int tab[1];
101 } CValue;
103 /* value on stack */
104 typedef struct SValue {
105 int t; /* type */
106 unsigned short r; /* register + flags */
107 unsigned short r2; /* second register, used for 'long long'
108 type. If not used, set to VT_CONST */
109 CValue c; /* constant, if VT_CONST */
110 } SValue;
112 /* symbol management */
113 typedef struct Sym {
114 int v; /* symbol token */
115 int t; /* associated type */
116 int r; /* associated register */
117 int c; /* associated number */
118 struct Sym *next; /* next related symbol */
119 struct Sym *prev; /* prev symbol in stack */
120 struct Sym *hash_next; /* next symbol in hash table */
121 } Sym;
123 typedef struct SymStack {
124 struct Sym *top;
125 struct Sym *hash[SYM_HASH_SIZE];
126 } SymStack;
128 /* section definition */
129 /* XXX: use directly ELF structure for parameters ? */
130 /* special flag to indicate that the section should not be linked to
131 the other ones */
132 #define SHF_PRIVATE 0x80000000
134 typedef struct Section {
135 unsigned char *data; /* section data */
136 unsigned char *data_ptr; /* current data pointer */
137 int sh_name; /* elf section name (only used during output) */
138 int sh_num; /* elf section number */
139 int sh_type; /* elf section type */
140 int sh_flags; /* elf section flags */
141 int sh_info; /* elf section info */
142 int sh_addralign; /* elf section alignment */
143 int sh_entsize; /* elf entry size */
144 unsigned long sh_size; /* section size (only used during output) */
145 unsigned long sh_addr; /* address at which the section is relocated */
146 unsigned long sh_offset; /* address at which the section is relocated */
147 struct Section *link; /* link to another section */
148 struct Section *reloc; /* corresponding section for relocation, if any */
149 struct Section *hash; /* hash table for symbols */
150 struct Section *next;
151 char name[64]; /* section name */
152 } Section;
154 /* GNUC attribute definition */
155 typedef struct AttributeDef {
156 int aligned;
157 Section *section;
158 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
159 } AttributeDef;
161 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
162 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
163 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
165 /* stored in 'Sym.c' field */
166 #define FUNC_NEW 1 /* ansi function prototype */
167 #define FUNC_OLD 2 /* old function prototype */
168 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
170 /* stored in 'Sym.r' field */
171 #define FUNC_CDECL 0 /* standard c call */
172 #define FUNC_STDCALL 1 /* pascal c call */
174 /* field 'Sym.t' for macros */
175 #define MACRO_OBJ 0 /* object like macro */
176 #define MACRO_FUNC 1 /* function like macro */
178 /* field 'Sym.t' for labels */
179 #define LABEL_FORWARD 1 /* label is forward defined */
181 /* type_decl() types */
182 #define TYPE_ABSTRACT 1 /* type without variable */
183 #define TYPE_DIRECT 2 /* type with variable */
185 #define IO_BUF_SIZE 8192
187 typedef struct BufferedFile {
188 unsigned char *buf_ptr;
189 unsigned char *buf_end;
190 int fd;
191 int line_num; /* current line number - here to simply code */
192 char filename[1024]; /* current filename - here to simply code */
193 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
194 } BufferedFile;
196 #define CH_EOB 0 /* end of buffer or '\0' char in file */
197 #define CH_EOF (-1) /* end of file */
199 /* parsing state (used to save parser state to reparse part of the
200 source several times) */
201 typedef struct ParseState {
202 int *macro_ptr;
203 int line_num;
204 int tok;
205 CValue tokc;
206 } ParseState;
208 /* used to record tokens */
209 typedef struct TokenString {
210 int *str;
211 int len;
212 int last_line_num;
213 } TokenString;
215 /* parser */
216 struct BufferedFile *file;
217 int ch, ch1, tok, tok1;
218 CValue tokc, tok1c;
220 /* sections */
221 /* XXX: suppress first_section */
222 Section *first_section, **sections;
223 int nb_sections; /* number of sections, including first dummy section */
224 int nb_allocated_sections;
225 Section *text_section, *data_section, *bss_section; /* predefined sections */
226 Section *cur_text_section; /* current section where function code is
227 generated */
228 /* bound check related sections */
229 Section *bounds_section; /* contains global data bound description */
230 Section *lbounds_section; /* contains local data bound description */
231 /* symbol sections */
232 Section *symtab_section, *strtab_section;
234 /* debug sections */
235 Section *stab_section, *stabstr_section;
237 /* loc : local variable index
238 ind : output code index
239 rsym: return symbol
240 anon_sym: anonymous symbol index
242 int rsym, anon_sym,
243 prog, ind, loc, const_wanted;
244 int global_expr; /* true if compound literals must be allocated
245 globally (used during initializers parsing */
246 int func_vt, func_vc; /* current function return type (used by
247 return instruction) */
248 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
249 int tok_ident;
250 TokenSym **table_ident;
251 TokenSym *hash_ident[TOK_HASH_SIZE];
252 char token_buf[STRING_MAX_SIZE + 1];
253 char *funcname;
254 SymStack define_stack, global_stack, local_stack, label_stack;
256 SValue vstack[VSTACK_SIZE], *vtop;
257 int *macro_ptr, *macro_ptr_allocated;
258 BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr;
259 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
260 char *include_paths[INCLUDE_PATHS_MAX];
261 int nb_include_paths;
262 int char_pointer_type;
264 /* compile with debug symbol (and use them if error during execution) */
265 int do_debug = 0;
267 /* compile with built-in memory and bounds checker */
268 int do_bounds_check = 0;
270 /* display benchmark infos */
271 int do_bench = 0;
272 int total_lines;
273 int total_bytes;
275 /* use GNU C extensions */
276 int gnu_ext = 1;
278 /* use Tiny C extensions */
279 int tcc_ext = 1;
281 /* if true, static linking is performed */
282 int static_link = 0;
284 struct TCCState {
285 int dummy;
288 /* The current value can be: */
289 #define VT_VALMASK 0x00ff
290 #define VT_CONST 0x00f0 /* constant in vc
291 (must be first non register value) */
292 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
293 #define VT_LOCAL 0x00f2 /* offset on stack */
294 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
295 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
296 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
297 #define VT_LVAL 0x0100 /* var is an lvalue */
298 #define VT_SYM 0x0200 /* a symbol value is added */
299 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
300 char/short stored in integer registers) */
301 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
302 dereferencing value */
303 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
304 bounding function call point is in vc */
305 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
306 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
307 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
308 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
310 /* types */
311 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
313 #define VT_INT 0 /* integer type */
314 #define VT_BYTE 1 /* signed byte type */
315 #define VT_SHORT 2 /* short type */
316 #define VT_VOID 3 /* void type */
317 #define VT_PTR 4 /* pointer */
318 #define VT_ENUM 5 /* enum definition */
319 #define VT_FUNC 6 /* function type */
320 #define VT_STRUCT 7 /* struct/union definition */
321 #define VT_FLOAT 8 /* IEEE float */
322 #define VT_DOUBLE 9 /* IEEE double */
323 #define VT_LDOUBLE 10 /* IEEE long double */
324 #define VT_BOOL 11 /* ISOC99 boolean type */
325 #define VT_LLONG 12 /* 64 bit integer */
326 #define VT_LONG 13 /* long integer (NEVER USED as type, only
327 during parsing) */
328 #define VT_BTYPE 0x000f /* mask for basic type */
329 #define VT_UNSIGNED 0x0010 /* unsigned type */
330 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
331 #define VT_BITFIELD 0x0040 /* bitfield modifier */
333 /* storage */
334 #define VT_EXTERN 0x00000080 /* extern definition */
335 #define VT_STATIC 0x00000100 /* static variable */
336 #define VT_TYPEDEF 0x00000200 /* typedef definition */
338 /* type mask (except storage) */
339 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
341 /* token values */
343 /* warning: the following compare tokens depend on i386 asm code */
344 #define TOK_ULT 0x92
345 #define TOK_UGE 0x93
346 #define TOK_EQ 0x94
347 #define TOK_NE 0x95
348 #define TOK_ULE 0x96
349 #define TOK_UGT 0x97
350 #define TOK_LT 0x9c
351 #define TOK_GE 0x9d
352 #define TOK_LE 0x9e
353 #define TOK_GT 0x9f
355 #define TOK_LAND 0xa0
356 #define TOK_LOR 0xa1
358 #define TOK_DEC 0xa2
359 #define TOK_MID 0xa3 /* inc/dec, to void constant */
360 #define TOK_INC 0xa4
361 #define TOK_UDIV 0xb0 /* unsigned division */
362 #define TOK_UMOD 0xb1 /* unsigned modulo */
363 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
364 #define TOK_CINT 0xb3 /* number in tokc */
365 #define TOK_CCHAR 0xb4 /* char constant in tokc */
366 #define TOK_STR 0xb5 /* pointer to string in tokc */
367 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
368 #define TOK_LCHAR 0xb7
369 #define TOK_LSTR 0xb8
370 #define TOK_CFLOAT 0xb9 /* float constant */
371 #define TOK_LINENUM 0xba /* line number info */
372 #define TOK_CDOUBLE 0xc0 /* double constant */
373 #define TOK_CLDOUBLE 0xc1 /* long double constant */
374 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
375 #define TOK_ADDC1 0xc3 /* add with carry generation */
376 #define TOK_ADDC2 0xc4 /* add with carry use */
377 #define TOK_SUBC1 0xc5 /* add with carry generation */
378 #define TOK_SUBC2 0xc6 /* add with carry use */
379 #define TOK_CUINT 0xc8 /* unsigned int constant */
380 #define TOK_CLLONG 0xc9 /* long long constant */
381 #define TOK_CULLONG 0xca /* unsigned long long constant */
382 #define TOK_ARROW 0xcb
383 #define TOK_DOTS 0xcc /* three dots */
384 #define TOK_SHR 0xcd /* unsigned shift right */
386 #define TOK_SHL 0x01 /* shift left */
387 #define TOK_SAR 0x02 /* signed shift right */
389 /* assignement operators : normal operator or 0x80 */
390 #define TOK_A_MOD 0xa5
391 #define TOK_A_AND 0xa6
392 #define TOK_A_MUL 0xaa
393 #define TOK_A_ADD 0xab
394 #define TOK_A_SUB 0xad
395 #define TOK_A_DIV 0xaf
396 #define TOK_A_XOR 0xde
397 #define TOK_A_OR 0xfc
398 #define TOK_A_SHL 0x81
399 #define TOK_A_SAR 0x82
401 #define TOK_EOF (-1) /* end of file */
403 /* all identificators and strings have token above that */
404 #define TOK_IDENT 256
406 enum {
407 TOK_INT = TOK_IDENT,
408 TOK_VOID,
409 TOK_CHAR,
410 TOK_IF,
411 TOK_ELSE,
412 TOK_WHILE,
413 TOK_BREAK,
414 TOK_RETURN,
415 TOK_FOR,
416 TOK_EXTERN,
417 TOK_STATIC,
418 TOK_UNSIGNED,
419 TOK_GOTO,
420 TOK_DO,
421 TOK_CONTINUE,
422 TOK_SWITCH,
423 TOK_CASE,
425 /* ignored types Must have contiguous values */
426 TOK_CONST,
427 TOK_VOLATILE,
428 TOK_LONG,
429 TOK_REGISTER,
430 TOK_SIGNED,
431 TOK___SIGNED__, /* gcc keyword */
432 TOK_AUTO,
433 TOK_INLINE,
434 TOK___INLINE__, /* gcc keyword */
435 TOK_RESTRICT,
437 /* unsupported type */
438 TOK_FLOAT,
439 TOK_DOUBLE,
440 TOK_BOOL,
442 TOK_SHORT,
443 TOK_STRUCT,
444 TOK_UNION,
445 TOK_TYPEDEF,
446 TOK_DEFAULT,
447 TOK_ENUM,
448 TOK_SIZEOF,
449 TOK___ATTRIBUTE__,
451 /* preprocessor only */
452 TOK_UIDENT, /* first "user" ident (not keyword) */
453 TOK_DEFINE = TOK_UIDENT,
454 TOK_INCLUDE,
455 TOK_IFDEF,
456 TOK_IFNDEF,
457 TOK_ELIF,
458 TOK_ENDIF,
459 TOK_DEFINED,
460 TOK_UNDEF,
461 TOK_ERROR,
462 TOK_LINE,
463 TOK___LINE__,
464 TOK___FILE__,
465 TOK___DATE__,
466 TOK___TIME__,
467 TOK___VA_ARGS__,
469 /* special identifiers */
470 TOK___FUNC__,
471 TOK_MAIN,
472 /* attribute identifiers */
473 TOK_SECTION,
474 TOK___SECTION__,
475 TOK_ALIGNED,
476 TOK___ALIGNED__,
477 TOK_UNUSED,
478 TOK___UNUSED__,
479 TOK_CDECL,
480 TOK___CDECL,
481 TOK___CDECL__,
482 TOK_STDCALL,
483 TOK___STDCALL,
484 TOK___STDCALL__,
485 TOK_NORETURN,
486 TOK___NORETURN__,
489 char *tcc_keywords =
490 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
491 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
492 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
493 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
494 "sizeof\0__attribute__\0"
495 /* the following are not keywords. They are included to ease parsing */
496 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
497 "defined\0undef\0error\0line\0"
498 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
499 "__func__\0main\0"
500 /* attributes */
501 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
502 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
503 "noreturn\0__noreturn__\0"
506 #ifdef WIN32
507 #define snprintf _snprintf
508 #endif
510 #if defined(WIN32) || defined(TCC_UCLIBC)
511 /* currently incorrect */
512 long double strtold(const char *nptr, char **endptr)
514 return (long double)strtod(nptr, endptr);
516 float strtof(const char *nptr, char **endptr)
518 return (float)strtod(nptr, endptr);
520 #else
521 /* XXX: need to define this to use them in non ISOC99 context */
522 extern float strtof (const char *__nptr, char **__endptr);
523 extern long double strtold (const char *__nptr, char **__endptr);
524 #endif
526 char *pstrcpy(char *buf, int buf_size, const char *s);
527 char *pstrcat(char *buf, int buf_size, const char *s);
529 void sum(int l);
530 void next(void);
531 void next_nomacro(void);
532 int expr_const(void);
533 void expr_eq(void);
534 void gexpr(void);
535 void decl(int l);
536 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only);
537 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
538 int v, int scope);
539 int gv(int rc);
540 void gv2(int rc1, int rc2);
541 void move_reg(int r, int s);
542 void save_regs(int n);
543 void save_reg(int r);
544 void vpop(void);
545 void vswap(void);
546 void vdup(void);
547 int get_reg(int rc);
549 void macro_subst(TokenString *tok_str,
550 Sym **nested_list, int *macro_str);
551 int save_reg_forced(int r);
552 void gen_op(int op);
553 void force_charshort_cast(int t);
554 void gen_cast(int t);
555 void vstore(void);
556 Sym *sym_find(int v);
557 Sym *sym_push(int v, int t, int r, int c);
559 /* type handling */
560 int type_size(int t, int *a);
561 int pointed_type(int t);
562 int pointed_size(int t);
563 int is_compatible_types(int t1, int t2);
564 int parse_btype(int *type_ptr, AttributeDef *ad);
565 int type_decl(AttributeDef *ad, int *v, int t, int td);
567 void error(const char *fmt, ...);
568 void rt_error(unsigned long pc, const char *fmt, ...);
569 void vpushi(int v);
570 void vset(int t, int r, int v);
571 void type_to_str(char *buf, int buf_size,
572 int t, const char *varstr);
573 char *get_tok_str(int v, CValue *cv);
575 /* section generation */
576 void put_extern_sym(Sym *sym, Section *section, unsigned long value);
577 void greloc(Section *s, Sym *sym, unsigned long addr, int type);
578 static int put_elf_str(Section *s, const char *sym);
579 static int put_elf_sym(Section *s,
580 unsigned long value, unsigned long size,
581 int info, int other, int shndx, const char *name);
582 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
583 int type, int symbol);
584 static void put_stabs(const char *str, int type, int other, int desc, int value);
585 static void put_stabn(int type, int other, int desc, int value);
586 static void put_stabd(int type, int other, int desc);
588 /* true if float/double/long double type */
589 static inline int is_float(int t)
591 int bt;
592 bt = t & VT_BTYPE;
593 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
596 #ifdef CONFIG_TCC_BCHECK
597 #include "bcheck.c"
598 #endif
600 #ifdef TCC_TARGET_I386
601 #include "i386-gen.c"
602 #endif
603 #ifdef TCC_TARGET_IL
604 #include "il-gen.c"
605 #endif
607 #ifdef CONFIG_TCC_STATIC
609 #define RTLD_LAZY 0x001
610 #define RTLD_NOW 0x002
611 #define RTLD_GLOBAL 0x100
613 /* dummy function for profiling */
614 void *dlopen(const char *filename, int flag)
616 return NULL;
619 const char *dlerror(void)
621 return "error";
624 typedef struct TCCSyms {
625 char *str;
626 void *ptr;
627 } TCCSyms;
629 #define TCCSYM(a) { #a, &a, },
631 /* add the symbol you want here if no dynamic linking is done */
632 static TCCSyms tcc_syms[] = {
633 TCCSYM(printf)
634 TCCSYM(fprintf)
635 TCCSYM(fopen)
636 TCCSYM(fclose)
637 { NULL, NULL },
640 void *dlsym(void *handle, const char *symbol)
642 TCCSyms *p;
643 p = tcc_syms;
644 while (p->str != NULL) {
645 if (!strcmp(p->str, symbol))
646 return p->ptr;
647 p++;
649 return NULL;
652 #endif
654 /********************************************************/
655 /* runtime library is there */
656 /* XXX: we suppose that the host compiler handles 'long long'. It
657 would not be difficult to suppress this assumption */
659 long long __divll(long long a, long long b)
661 return a / b;
664 long long __modll(long long a, long long b)
666 return a % b;
669 unsigned long long __divull(unsigned long long a, unsigned long long b)
671 return a / b;
674 unsigned long long __modull(unsigned long long a, unsigned long long b)
676 return a % b;
679 long long __sardi3(long long a, int b)
681 return a >> b;
684 unsigned long long __shrdi3(unsigned long long a, int b)
686 return a >> b;
689 long long __shldi3(long long a, int b)
691 return a << b;
694 float __ulltof(unsigned long long a)
696 return (float)a;
699 double __ulltod(unsigned long long a)
701 return (double)a;
704 long double __ulltold(unsigned long long a)
706 return (long double)a;
709 unsigned long long __ftoull(float a)
711 return (unsigned long long)a;
714 unsigned long long __dtoull(double a)
716 return (unsigned long long)a;
719 unsigned long long __ldtoull(long double a)
721 return (unsigned long long)a;
725 /********************************************************/
727 /* we use our own 'finite' function to avoid potential problems with
728 non standard math libs */
729 /* XXX: endianness dependant */
730 int ieee_finite(double d)
732 int *p = (int *)&d;
733 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
736 /* copy a string and truncate it. */
737 char *pstrcpy(char *buf, int buf_size, const char *s)
739 char *q, *q_end;
740 int c;
742 if (buf_size > 0) {
743 q = buf;
744 q_end = buf + buf_size - 1;
745 while (q < q_end) {
746 c = *s++;
747 if (c == '\0')
748 break;
749 *q++ = c;
751 *q = '\0';
753 return buf;
756 /* strcat and truncate. */
757 char *pstrcat(char *buf, int buf_size, const char *s)
759 int len;
760 len = strlen(buf);
761 if (len < buf_size)
762 pstrcpy(buf + len, buf_size - len, s);
763 return buf;
766 Section *new_section(const char *name, int sh_type, int sh_flags)
768 Section *sec, **psec;
769 void *data;
771 sec = malloc(sizeof(Section));
772 if (!sec)
773 error("memory full");
774 memset(sec, 0, sizeof(Section));
775 pstrcpy(sec->name, sizeof(sec->name), name);
776 sec->sh_type = sh_type;
777 sec->sh_flags = sh_flags;
778 switch(sh_type) {
779 case SHT_HASH:
780 case SHT_REL:
781 case SHT_DYNSYM:
782 case SHT_SYMTAB:
783 case SHT_DYNAMIC:
784 sec->sh_addralign = 4;
785 break;
786 case SHT_STRTAB:
787 sec->sh_addralign = 1;
788 break;
789 default:
790 sec->sh_addralign = 32; /* default conservative alignment */
791 break;
793 #ifdef WIN32
794 /* XXX: currently, a single malloc */
795 data = malloc(SECTION_VSIZE);
796 if (data == NULL)
797 error("could not alloc section '%s'", name);
798 #else
799 data = mmap(NULL, SECTION_VSIZE,
800 PROT_EXEC | PROT_READ | PROT_WRITE,
801 MAP_PRIVATE | MAP_ANONYMOUS,
802 -1, 0);
803 if (data == (void *)(-1))
804 error("could not mmap section '%s'", name);
805 #endif
806 sec->data = data;
807 sec->data_ptr = data;
809 if (!(sh_flags & SHF_PRIVATE)) {
810 /* only add section if not private */
812 psec = &first_section;
813 while (*psec != NULL)
814 psec = &(*psec)->next;
815 sec->next = NULL;
816 *psec = sec;
818 if ((nb_sections + 1) > nb_allocated_sections) {
819 if (nb_allocated_sections == 0)
820 nb_allocated_sections = 1;
821 nb_allocated_sections *= 2;
822 sections = realloc(sections,
823 nb_allocated_sections * sizeof(Section *));
824 if (!sections)
825 error("memory full");
827 sections[nb_sections] = sec;
828 sec->sh_num = nb_sections;
829 nb_sections++;
831 return sec;
834 /* return a reference to a section, and create it if it does not
835 exists */
836 Section *find_section(const char *name)
838 Section *sec;
840 for(sec = first_section; sec != NULL; sec = sec->next) {
841 if (!strcmp(name, sec->name))
842 return sec;
844 /* sections are created as PROGBITS */
845 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
848 /* add a new relocation entry to symbol 'sym' in section 's' */
849 void greloc(Section *s, Sym *sym, unsigned long offset, int type)
851 if (!sym->c)
852 put_extern_sym(sym, NULL, 0);
853 /* now we can add ELF relocation info */
854 put_elf_reloc(symtab_section, s, offset, type, sym->c);
857 static inline int isid(int c)
859 return (c >= 'a' && c <= 'z') ||
860 (c >= 'A' && c <= 'Z') ||
861 c == '_';
864 static inline int isnum(int c)
866 return c >= '0' && c <= '9';
869 static inline int toup(int c)
871 if (ch >= 'a' && ch <= 'z')
872 return ch - 'a' + 'A';
873 else
874 return ch;
877 void printline(void)
879 BufferedFile **f;
880 if (file) {
881 for(f = include_stack; f < include_stack_ptr; f++)
882 fprintf(stderr, "In file included from %s:%d:\n",
883 (*f)->filename, (*f)->line_num);
884 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
885 } else {
886 fprintf(stderr, "tcc: ");
890 void error(const char *fmt, ...)
892 va_list ap;
893 va_start(ap, fmt);
894 printline();
895 vfprintf(stderr, fmt, ap);
896 fprintf(stderr, "\n");
897 exit(1);
898 va_end(ap);
901 void expect(const char *msg)
903 error("%s expected", msg);
906 void warning(const char *fmt, ...)
908 va_list ap;
910 va_start(ap, fmt);
911 printline();
912 fprintf(stderr, "warning: ");
913 vfprintf(stderr, fmt, ap);
914 fprintf(stderr, "\n");
915 va_end(ap);
918 void skip(int c)
920 if (tok != c)
921 error("'%c' expected", c);
922 next();
925 void test_lvalue(void)
927 if (!(vtop->r & VT_LVAL))
928 expect("lvalue");
931 TokenSym *tok_alloc(const char *str, int len)
933 TokenSym *ts, **pts, **ptable;
934 int h, i;
936 if (len <= 0)
937 len = strlen(str);
938 h = 1;
939 for(i=0;i<len;i++)
940 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
942 pts = &hash_ident[h];
943 while (1) {
944 ts = *pts;
945 if (!ts)
946 break;
947 if (ts->len == len && !memcmp(ts->str, str, len))
948 return ts;
949 pts = &(ts->hash_next);
952 if (tok_ident >= SYM_FIRST_ANOM)
953 error("memory full");
955 /* expand token table if needed */
956 i = tok_ident - TOK_IDENT;
957 if ((i % TOK_ALLOC_INCR) == 0) {
958 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
959 if (!ptable)
960 error("memory full");
961 table_ident = ptable;
964 ts = malloc(sizeof(TokenSym) + len);
965 if (!ts)
966 error("memory full");
967 table_ident[i] = ts;
968 ts->tok = tok_ident++;
969 ts->len = len;
970 ts->hash_next = NULL;
971 memcpy(ts->str, str, len + 1);
972 *pts = ts;
973 return ts;
976 void add_char(char **pp, int c)
978 char *p;
979 p = *pp;
980 if (c == '\'' || c == '\"' || c == '\\') {
981 /* XXX: could be more precise if char or string */
982 *p++ = '\\';
984 if (c >= 32 && c <= 126) {
985 *p++ = c;
986 } else {
987 *p++ = '\\';
988 if (c == '\n') {
989 *p++ = 'n';
990 } else {
991 *p++ = '0' + ((c >> 6) & 7);
992 *p++ = '0' + ((c >> 3) & 7);
993 *p++ = '0' + (c & 7);
996 *pp = p;
999 /* XXX: buffer overflow */
1000 char *get_tok_str(int v, CValue *cv)
1002 static char buf[STRING_MAX_SIZE + 1];
1003 TokenSym *ts;
1004 char *p;
1005 int i;
1007 if (v == TOK_CINT || v == TOK_CUINT) {
1008 sprintf(buf, "%u", cv->ui);
1009 return buf;
1010 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
1011 p = buf;
1012 *p++ = '\'';
1013 add_char(&p, cv->i);
1014 *p++ = '\'';
1015 *p = '\0';
1016 return buf;
1017 } else if (v == TOK_STR || v == TOK_LSTR) {
1018 ts = cv->ts;
1019 p = buf;
1020 *p++ = '\"';
1021 for(i=0;i<ts->len;i++)
1022 add_char(&p, ts->str[i]);
1023 *p++ = '\"';
1024 *p = '\0';
1025 return buf;
1026 } else if (v < TOK_IDENT) {
1027 p = buf;
1028 *p++ = v;
1029 *p = '\0';
1030 return buf;
1031 } else if (v < tok_ident) {
1032 return table_ident[v - TOK_IDENT]->str;
1033 } else if (v >= SYM_FIRST_ANOM) {
1034 /* special name for anonymous symbol */
1035 sprintf(buf, "L.%u", v - SYM_FIRST_ANOM);
1036 return buf;
1037 } else {
1038 /* should never happen */
1039 return NULL;
1043 /* push, without hashing */
1044 Sym *sym_push2(Sym **ps, int v, int t, int c)
1046 Sym *s;
1047 s = malloc(sizeof(Sym));
1048 if (!s)
1049 error("memory full");
1050 s->v = v;
1051 s->t = t;
1052 s->c = c;
1053 s->next = NULL;
1054 /* add in stack */
1055 s->prev = *ps;
1056 *ps = s;
1057 return s;
1060 /* find a symbol and return its associated structure. 's' is the top
1061 of the symbol stack */
1062 Sym *sym_find2(Sym *s, int v)
1064 while (s) {
1065 if (s->v == v)
1066 return s;
1067 s = s->prev;
1069 return NULL;
1072 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1074 /* find a symbol and return its associated structure. 'st' is the
1075 symbol stack */
1076 Sym *sym_find1(SymStack *st, int v)
1078 Sym *s;
1080 s = st->hash[HASH_SYM(v)];
1081 while (s) {
1082 if (s->v == v)
1083 return s;
1084 s = s->hash_next;
1086 return NULL;
1089 Sym *sym_push1(SymStack *st, int v, int t, int c)
1091 Sym *s, **ps;
1092 s = sym_push2(&st->top, v, t, c);
1093 /* add in hash table */
1094 if (v) {
1095 ps = &st->hash[HASH_SYM(v)];
1096 s->hash_next = *ps;
1097 *ps = s;
1099 return s;
1102 /* find a symbol in the right symbol space */
1103 Sym *sym_find(int v)
1105 Sym *s;
1106 s = sym_find1(&local_stack, v);
1107 if (!s)
1108 s = sym_find1(&global_stack, v);
1109 return s;
1112 /* push a given symbol on the symbol stack */
1113 Sym *sym_push(int v, int t, int r, int c)
1115 Sym *s;
1116 if (local_stack.top)
1117 s = sym_push1(&local_stack, v, t, c);
1118 else
1119 s = sym_push1(&global_stack, v, t, c);
1120 s->r = r;
1121 return s;
1124 /* pop symbols until top reaches 'b' */
1125 void sym_pop(SymStack *st, Sym *b)
1127 Sym *s, *ss;
1129 s = st->top;
1130 while(s != b) {
1131 ss = s->prev;
1132 /* free hash table entry, except if symbol was freed (only
1133 used for #undef symbols) */
1134 if (s->v)
1135 st->hash[HASH_SYM(s->v)] = s->hash_next;
1136 free(s);
1137 s = ss;
1139 st->top = b;
1142 /* undefined a hashed symbol (used for #undef). Its name is set to
1143 zero */
1144 void sym_undef(SymStack *st, Sym *s)
1146 Sym **ss;
1147 ss = &st->hash[HASH_SYM(s->v)];
1148 while (*ss != NULL) {
1149 if (*ss == s)
1150 break;
1151 ss = &(*ss)->hash_next;
1153 *ss = s->hash_next;
1154 s->v = 0;
1157 /* I/O layer */
1159 BufferedFile *tcc_open(const char *filename)
1161 int fd;
1162 BufferedFile *bf;
1164 fd = open(filename, O_RDONLY);
1165 if (fd < 0)
1166 return NULL;
1167 bf = malloc(sizeof(BufferedFile));
1168 if (!bf) {
1169 close(fd);
1170 return NULL;
1172 bf->fd = fd;
1173 bf->buf_ptr = bf->buffer;
1174 bf->buf_end = bf->buffer;
1175 bf->buffer[0] = CH_EOB; /* put eob symbol */
1176 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1177 bf->line_num = 1;
1178 // printf("opening '%s'\n", filename);
1179 return bf;
1182 void tcc_close(BufferedFile *bf)
1184 total_lines += bf->line_num;
1185 close(bf->fd);
1186 free(bf);
1189 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1190 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1192 /* fill input buffer and return next char */
1193 int tcc_getc_slow(BufferedFile *bf)
1195 int len;
1196 /* only tries to read if really end of buffer */
1197 if (bf->buf_ptr >= bf->buf_end) {
1198 if (bf->fd != -1) {
1199 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1200 if (len < 0)
1201 len = 0;
1202 } else {
1203 len = 0;
1205 total_bytes += len;
1206 bf->buf_ptr = bf->buffer;
1207 bf->buf_end = bf->buffer + len;
1208 *bf->buf_end = CH_EOB;
1210 if (bf->buf_ptr < bf->buf_end) {
1211 return *bf->buf_ptr++;
1212 } else {
1213 bf->buf_ptr = bf->buf_end;
1214 return CH_EOF;
1218 /* no need to put that inline */
1219 void handle_eob(void)
1221 for(;;) {
1222 ch1 = tcc_getc_slow(file);
1223 if (ch1 != CH_EOF)
1224 return;
1226 if (include_stack_ptr == include_stack)
1227 return;
1228 /* add end of include file debug info */
1229 if (do_debug) {
1230 put_stabd(N_EINCL, 0, 0);
1232 /* pop include stack */
1233 tcc_close(file);
1234 include_stack_ptr--;
1235 file = *include_stack_ptr;
1239 /* read next char from current input file */
1240 static inline void inp(void)
1242 ch1 = TCC_GETC(file);
1243 /* end of buffer/file handling */
1244 if (ch1 == CH_EOB)
1245 handle_eob();
1246 if (ch1 == '\n')
1247 file->line_num++;
1248 // printf("ch1=%c 0x%x\n", ch1, ch1);
1251 /* input with '\\n' handling */
1252 static inline void minp(void)
1254 redo:
1255 ch = ch1;
1256 inp();
1257 if (ch == '\\' && ch1 == '\n') {
1258 inp();
1259 goto redo;
1261 //printf("ch=%c 0x%x\n", ch, ch);
1265 /* same as minp, but also skip comments */
1266 void cinp(void)
1268 int c;
1270 if (ch1 == '/') {
1271 inp();
1272 if (ch1 == '/') {
1273 /* single line C++ comments */
1274 inp();
1275 while (ch1 != '\n' && ch1 != -1)
1276 inp();
1277 inp();
1278 ch = ' '; /* return space */
1279 } else if (ch1 == '*') {
1280 /* C comments */
1281 inp();
1282 while (ch1 != -1) {
1283 c = ch1;
1284 inp();
1285 if (c == '*' && ch1 == '/') {
1286 inp();
1287 ch = ' '; /* return space */
1288 break;
1291 } else {
1292 ch = '/';
1294 } else {
1295 minp();
1299 void skip_spaces(void)
1301 while (ch == ' ' || ch == '\t')
1302 cinp();
1305 /* skip block of text until #else, #elif or #endif. skip also pairs of
1306 #if/#endif */
1307 void preprocess_skip(void)
1309 int a;
1310 a = 0;
1311 while (1) {
1312 while (ch != '\n') {
1313 if (ch == -1)
1314 expect("#endif");
1315 cinp();
1317 cinp();
1318 skip_spaces();
1319 if (ch == '#') {
1320 cinp();
1321 next_nomacro();
1322 if (a == 0 &&
1323 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1324 break;
1325 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1326 a++;
1327 else if (tok == TOK_ENDIF)
1328 a--;
1333 /* ParseState handling */
1335 /* XXX: currently, no include file info is stored. Thus, we cannot display
1336 accurate messages if the function or data definition spans multiple
1337 files */
1339 /* save current parse state in 's' */
1340 void save_parse_state(ParseState *s)
1342 s->line_num = file->line_num;
1343 s->macro_ptr = macro_ptr;
1344 s->tok = tok;
1345 s->tokc = tokc;
1348 /* restore parse state from 's' */
1349 void restore_parse_state(ParseState *s)
1351 file->line_num = s->line_num;
1352 macro_ptr = s->macro_ptr;
1353 tok = s->tok;
1354 tokc = s->tokc;
1357 /* return the number of additionnal 'ints' necessary to store the
1358 token */
1359 static inline int tok_ext_size(int t)
1361 switch(t) {
1362 /* 4 bytes */
1363 case TOK_CINT:
1364 case TOK_CUINT:
1365 case TOK_CCHAR:
1366 case TOK_LCHAR:
1367 case TOK_STR:
1368 case TOK_LSTR:
1369 case TOK_CFLOAT:
1370 case TOK_LINENUM:
1371 return 1;
1372 case TOK_CDOUBLE:
1373 case TOK_CLLONG:
1374 case TOK_CULLONG:
1375 return 2;
1376 case TOK_CLDOUBLE:
1377 return LDOUBLE_SIZE / 4;
1378 default:
1379 return 0;
1383 /* token string handling */
1385 static inline void tok_str_new(TokenString *s)
1387 s->str = NULL;
1388 s->len = 0;
1389 s->last_line_num = -1;
1392 static void tok_str_add(TokenString *s, int t)
1394 int len, *str;
1396 len = s->len;
1397 str = s->str;
1398 if ((len & 63) == 0) {
1399 str = realloc(str, (len + 64) * sizeof(int));
1400 if (!str)
1401 return;
1402 s->str = str;
1404 str[len++] = t;
1405 s->len = len;
1408 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1410 int n, i;
1411 tok_str_add(s, t);
1412 n = tok_ext_size(t);
1413 for(i=0;i<n;i++)
1414 tok_str_add(s, cv->tab[i]);
1417 /* add the current parse token in token string 's' */
1418 static void tok_str_add_tok(TokenString *s)
1420 CValue cval;
1422 /* save line number info */
1423 if (file->line_num != s->last_line_num) {
1424 s->last_line_num = file->line_num;
1425 cval.i = s->last_line_num;
1426 tok_str_add2(s, TOK_LINENUM, &cval);
1428 tok_str_add2(s, tok, &tokc);
1431 /* get a token from an integer array and increment pointer accordingly */
1432 static int tok_get(int **tok_str, CValue *cv)
1434 int *p, t, n, i;
1436 p = *tok_str;
1437 t = *p++;
1438 n = tok_ext_size(t);
1439 for(i=0;i<n;i++)
1440 cv->tab[i] = *p++;
1441 *tok_str = p;
1442 return t;
1445 /* eval an expression for #if/#elif */
1446 int expr_preprocess(void)
1448 int c, t;
1449 TokenString str;
1451 tok_str_new(&str);
1452 while (1) {
1453 skip_spaces();
1454 if (ch == '\n')
1455 break;
1456 next(); /* do macro subst */
1457 if (tok == TOK_DEFINED) {
1458 next_nomacro();
1459 t = tok;
1460 if (t == '(')
1461 next_nomacro();
1462 c = sym_find1(&define_stack, tok) != 0;
1463 if (t == '(')
1464 next_nomacro();
1465 tok = TOK_CINT;
1466 tokc.i = c;
1467 } else if (tok >= TOK_IDENT) {
1468 /* if undefined macro */
1469 tok = TOK_CINT;
1470 tokc.i = 0;
1472 tok_str_add_tok(&str);
1474 tok_str_add(&str, -1); /* simulate end of file */
1475 tok_str_add(&str, 0);
1476 /* now evaluate C constant expression */
1477 macro_ptr = str.str;
1478 next();
1479 c = expr_const();
1480 macro_ptr = NULL;
1481 free(str.str);
1482 return c != 0;
1485 #if defined(DEBUG) || defined(PP_DEBUG)
1486 void tok_print(int *str)
1488 int t;
1489 CValue cval;
1491 while (1) {
1492 t = tok_get(&str, &cval);
1493 if (!t)
1494 break;
1495 printf(" %s", get_tok_str(t, &cval));
1497 printf("\n");
1499 #endif
1501 /* parse after #define */
1502 void parse_define(void)
1504 Sym *s, *first, **ps;
1505 int v, t, varg, is_vaargs;
1506 TokenString str;
1508 v = tok;
1509 /* XXX: should check if same macro (ANSI) */
1510 first = NULL;
1511 t = MACRO_OBJ;
1512 /* '(' must be just after macro definition for MACRO_FUNC */
1513 if (ch == '(') {
1514 next_nomacro();
1515 next_nomacro();
1516 ps = &first;
1517 while (tok != ')') {
1518 varg = tok;
1519 next_nomacro();
1520 is_vaargs = 0;
1521 if (varg == TOK_DOTS) {
1522 varg = TOK___VA_ARGS__;
1523 is_vaargs = 1;
1524 } else if (tok == TOK_DOTS && gnu_ext) {
1525 is_vaargs = 1;
1526 next_nomacro();
1528 if (varg < TOK_IDENT)
1529 error("badly punctuated parameter list");
1530 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1531 *ps = s;
1532 ps = &s->next;
1533 if (tok != ',')
1534 break;
1535 next_nomacro();
1537 t = MACRO_FUNC;
1539 tok_str_new(&str);
1540 while (1) {
1541 skip_spaces();
1542 if (ch == '\n' || ch == -1)
1543 break;
1544 next_nomacro();
1545 tok_str_add2(&str, tok, &tokc);
1547 tok_str_add(&str, 0);
1548 #ifdef PP_DEBUG
1549 printf("define %s %d: ", get_tok_str(v, NULL), t);
1550 tok_print(str);
1551 #endif
1552 s = sym_push1(&define_stack, v, t, (int)str.str);
1553 s->next = first;
1556 void preprocess(void)
1558 int size, i, c;
1559 char buf[1024], *q, *p;
1560 char buf1[1024];
1561 BufferedFile *f;
1562 Sym *s;
1564 cinp();
1565 next_nomacro();
1566 redo:
1567 if (tok == TOK_DEFINE) {
1568 next_nomacro();
1569 parse_define();
1570 } else if (tok == TOK_UNDEF) {
1571 next_nomacro();
1572 s = sym_find1(&define_stack, tok);
1573 /* undefine symbol by putting an invalid name */
1574 if (s)
1575 sym_undef(&define_stack, s);
1576 } else if (tok == TOK_INCLUDE) {
1577 skip_spaces();
1578 if (ch == '<') {
1579 c = '>';
1580 goto read_name;
1581 } else if (ch == '\"') {
1582 c = ch;
1583 read_name:
1584 minp();
1585 q = buf;
1586 while (ch != c && ch != '\n' && ch != -1) {
1587 if ((q - buf) < sizeof(buf) - 1)
1588 *q++ = ch;
1589 minp();
1591 *q = '\0';
1592 } else {
1593 next();
1594 if (tok != TOK_STR)
1595 error("#include syntax error");
1596 pstrcpy(buf, sizeof(buf), get_tok_str(tok, &tokc));
1597 c = '\"';
1599 /* eat all spaces and comments after include */
1600 /* XXX: slightly incorrect */
1601 while (ch1 != '\n' && ch1 != -1)
1602 inp();
1604 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1605 error("memory full");
1606 if (c == '\"') {
1607 /* first search in current dir if "header.h" */
1608 size = 0;
1609 p = strrchr(file->filename, '/');
1610 if (p)
1611 size = p + 1 - file->filename;
1612 if (size > sizeof(buf1) - 1)
1613 size = sizeof(buf1) - 1;
1614 memcpy(buf1, file->filename, size);
1615 buf1[size] = '\0';
1616 pstrcat(buf1, sizeof(buf1), buf);
1617 f = tcc_open(buf1);
1618 if (f)
1619 goto found;
1621 /* now search in standard include path */
1622 for(i=nb_include_paths - 1;i>=0;i--) {
1623 strcpy(buf1, include_paths[i]);
1624 strcat(buf1, "/");
1625 strcat(buf1, buf);
1626 f = tcc_open(buf1);
1627 if (f)
1628 goto found;
1630 error("include file '%s' not found", buf);
1631 f = NULL;
1632 found:
1633 /* push current file in stack */
1634 /* XXX: fix current line init */
1635 *include_stack_ptr++ = file;
1636 file = f;
1637 /* add include file debug info */
1638 if (do_debug) {
1639 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1641 } else if (tok == TOK_IFNDEF) {
1642 c = 1;
1643 goto do_ifdef;
1644 } else if (tok == TOK_IF) {
1645 c = expr_preprocess();
1646 goto do_if;
1647 } else if (tok == TOK_IFDEF) {
1648 c = 0;
1649 do_ifdef:
1650 next_nomacro();
1651 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1652 do_if:
1653 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1654 error("memory full");
1655 *ifdef_stack_ptr++ = c;
1656 goto test_skip;
1657 } else if (tok == TOK_ELSE) {
1658 if (ifdef_stack_ptr == ifdef_stack)
1659 error("#else without matching #if");
1660 if (ifdef_stack_ptr[-1] & 2)
1661 error("#else after #else");
1662 c = (ifdef_stack_ptr[-1] ^= 3);
1663 goto test_skip;
1664 } else if (tok == TOK_ELIF) {
1665 if (ifdef_stack_ptr == ifdef_stack)
1666 error("#elif without matching #if");
1667 c = ifdef_stack_ptr[-1];
1668 if (c > 1)
1669 error("#elif after #else");
1670 /* last #if/#elif expression was true: we skip */
1671 if (c == 1)
1672 goto skip;
1673 c = expr_preprocess();
1674 ifdef_stack_ptr[-1] = c;
1675 test_skip:
1676 if (!(c & 1)) {
1677 skip:
1678 preprocess_skip();
1679 goto redo;
1681 } else if (tok == TOK_ENDIF) {
1682 if (ifdef_stack_ptr == ifdef_stack)
1683 error("#endif without matching #if");
1684 ifdef_stack_ptr--;
1685 } else if (tok == TOK_LINE) {
1686 next();
1687 if (tok != TOK_CINT)
1688 error("#line");
1689 file->line_num = tokc.i;
1690 skip_spaces();
1691 if (ch != '\n') {
1692 next();
1693 if (tok != TOK_STR)
1694 error("#line");
1695 pstrcpy(file->filename, sizeof(file->filename),
1696 get_tok_str(tok, &tokc));
1698 } else if (tok == TOK_ERROR) {
1699 error("#error");
1701 /* ignore other preprocess commands or #! for C scripts */
1702 while (ch != '\n' && ch != -1)
1703 cinp();
1706 /* read a number in base b */
1707 int getn(b)
1709 int n, t;
1710 n = 0;
1711 while (1) {
1712 if (ch >= 'a' && ch <= 'f')
1713 t = ch - 'a' + 10;
1714 else if (ch >= 'A' && ch <= 'F')
1715 t = ch - 'A' + 10;
1716 else if (isnum(ch))
1717 t = ch - '0';
1718 else
1719 break;
1720 if (t < 0 || t >= b)
1721 break;
1722 n = n * b + t;
1723 cinp();
1725 return n;
1728 /* read a character for string or char constant and eval escape codes */
1729 int getq()
1731 int c;
1733 c = ch;
1734 minp();
1735 if (c == '\\') {
1736 if (isnum(ch)) {
1737 /* at most three octal digits */
1738 c = ch - '0';
1739 minp();
1740 if (isnum(ch)) {
1741 c = c * 8 + ch - '0';
1742 minp();
1743 if (isnum(ch)) {
1744 c = c * 8 + ch - '0';
1745 minp();
1748 return c;
1749 } else if (ch == 'x') {
1750 minp();
1751 return getn(16);
1752 } else {
1753 if (ch == 'a')
1754 c = '\a';
1755 else if (ch == 'b')
1756 c = '\b';
1757 else if (ch == 'f')
1758 c = '\f';
1759 else if (ch == 'n')
1760 c = '\n';
1761 else if (ch == 'r')
1762 c = '\r';
1763 else if (ch == 't')
1764 c = '\t';
1765 else if (ch == 'v')
1766 c = '\v';
1767 else if (ch == 'e' && gnu_ext)
1768 c = 27;
1769 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1770 c = ch;
1771 else
1772 error("invalid escaped char");
1773 minp();
1776 return c;
1779 /* we use 64 bit numbers */
1780 #define BN_SIZE 2
1782 /* bn = (bn << shift) | or_val */
1783 void bn_lshift(unsigned int *bn, int shift, int or_val)
1785 int i;
1786 unsigned int v;
1787 for(i=0;i<BN_SIZE;i++) {
1788 v = bn[i];
1789 bn[i] = (v << shift) | or_val;
1790 or_val = v >> (32 - shift);
1794 void bn_zero(unsigned int *bn)
1796 int i;
1797 for(i=0;i<BN_SIZE;i++) {
1798 bn[i] = 0;
1802 void parse_number(void)
1804 int b, t, shift, frac_bits, s, exp_val;
1805 char *q;
1806 unsigned int bn[BN_SIZE];
1807 double d;
1809 /* number */
1810 q = token_buf;
1811 t = ch;
1812 cinp();
1813 *q++ = t;
1814 b = 10;
1815 if (t == '.') {
1816 /* special dot handling */
1817 if (ch >= '0' && ch <= '9') {
1818 goto float_frac_parse;
1819 } else if (ch == '.') {
1820 cinp();
1821 if (ch != '.')
1822 expect("'.'");
1823 cinp();
1824 tok = TOK_DOTS;
1825 } else {
1826 /* dots */
1827 tok = t;
1829 return;
1830 } else if (t == '0') {
1831 if (ch == 'x' || ch == 'X') {
1832 q--;
1833 cinp();
1834 b = 16;
1835 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1836 q--;
1837 cinp();
1838 b = 2;
1841 /* parse all digits. cannot check octal numbers at this stage
1842 because of floating point constants */
1843 while (1) {
1844 if (ch >= 'a' && ch <= 'f')
1845 t = ch - 'a' + 10;
1846 else if (ch >= 'A' && ch <= 'F')
1847 t = ch - 'A' + 10;
1848 else if (isnum(ch))
1849 t = ch - '0';
1850 else
1851 break;
1852 if (t >= b)
1853 break;
1854 if (q >= token_buf + STRING_MAX_SIZE) {
1855 num_too_long:
1856 error("number too long");
1858 *q++ = ch;
1859 cinp();
1861 if (ch == '.' ||
1862 ((ch == 'e' || ch == 'E') && b == 10) ||
1863 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1864 if (b != 10) {
1865 /* NOTE: strtox should support that for hexa numbers, but
1866 non ISOC99 libcs do not support it, so we prefer to do
1867 it by hand */
1868 /* hexadecimal or binary floats */
1869 /* XXX: handle overflows */
1870 *q = '\0';
1871 if (b == 16)
1872 shift = 4;
1873 else
1874 shift = 2;
1875 bn_zero(bn);
1876 q = token_buf;
1877 while (1) {
1878 t = *q++;
1879 if (t == '\0') {
1880 break;
1881 } else if (t >= 'a') {
1882 t = t - 'a' + 10;
1883 } else if (t >= 'A') {
1884 t = t - 'A' + 10;
1885 } else {
1886 t = t - '0';
1888 bn_lshift(bn, shift, t);
1890 frac_bits = 0;
1891 if (ch == '.') {
1892 cinp();
1893 while (1) {
1894 t = ch;
1895 if (t >= 'a' && t <= 'f') {
1896 t = t - 'a' + 10;
1897 } else if (t >= 'A' && t <= 'F') {
1898 t = t - 'A' + 10;
1899 } else if (t >= '0' && t <= '9') {
1900 t = t - '0';
1901 } else {
1902 break;
1904 if (t >= b)
1905 error("invalid digit");
1906 bn_lshift(bn, shift, t);
1907 frac_bits += shift;
1908 cinp();
1911 if (ch != 'p' && ch != 'P')
1912 error("exponent expected");
1913 cinp();
1914 s = 1;
1915 exp_val = 0;
1916 if (ch == '+') {
1917 cinp();
1918 } else if (ch == '-') {
1919 s = -1;
1920 cinp();
1922 if (ch < '0' || ch > '9')
1923 error("exponent digits expected");
1924 while (ch >= '0' && ch <= '9') {
1925 exp_val = exp_val * 10 + ch - '0';
1926 cinp();
1928 exp_val = exp_val * s;
1930 /* now we can generate the number */
1931 /* XXX: should patch directly float number */
1932 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1933 d = ldexp(d, exp_val - frac_bits);
1934 t = toup(ch);
1935 if (t == 'F') {
1936 cinp();
1937 tok = TOK_CFLOAT;
1938 /* float : should handle overflow */
1939 tokc.f = (float)d;
1940 } else if (t == 'L') {
1941 cinp();
1942 tok = TOK_CLDOUBLE;
1943 /* XXX: not large enough */
1944 tokc.ld = (long double)d;
1945 } else {
1946 tok = TOK_CDOUBLE;
1947 tokc.d = d;
1949 } else {
1950 /* decimal floats */
1951 if (ch == '.') {
1952 if (q >= token_buf + STRING_MAX_SIZE)
1953 goto num_too_long;
1954 *q++ = ch;
1955 cinp();
1956 float_frac_parse:
1957 while (ch >= '0' && ch <= '9') {
1958 if (q >= token_buf + STRING_MAX_SIZE)
1959 goto num_too_long;
1960 *q++ = ch;
1961 cinp();
1964 if (ch == 'e' || ch == 'E') {
1965 if (q >= token_buf + STRING_MAX_SIZE)
1966 goto num_too_long;
1967 *q++ = ch;
1968 cinp();
1969 if (ch == '-' || ch == '+') {
1970 if (q >= token_buf + STRING_MAX_SIZE)
1971 goto num_too_long;
1972 *q++ = ch;
1973 cinp();
1975 if (ch < '0' || ch > '9')
1976 error("exponent digits expected");
1977 while (ch >= '0' && ch <= '9') {
1978 if (q >= token_buf + STRING_MAX_SIZE)
1979 goto num_too_long;
1980 *q++ = ch;
1981 cinp();
1984 *q = '\0';
1985 t = toup(ch);
1986 errno = 0;
1987 if (t == 'F') {
1988 cinp();
1989 tok = TOK_CFLOAT;
1990 tokc.f = strtof(token_buf, NULL);
1991 } else if (t == 'L') {
1992 cinp();
1993 tok = TOK_CLDOUBLE;
1994 tokc.ld = strtold(token_buf, NULL);
1995 } else {
1996 tok = TOK_CDOUBLE;
1997 tokc.d = strtod(token_buf, NULL);
2000 } else {
2001 unsigned long long n, n1;
2002 int lcount;
2004 /* integer number */
2005 *q = '\0';
2006 q = token_buf;
2007 if (b == 10 && *q == '0') {
2008 b = 8;
2009 q++;
2011 n = 0;
2012 while(1) {
2013 t = *q++;
2014 /* no need for checks except for base 10 / 8 errors */
2015 if (t == '\0') {
2016 break;
2017 } else if (t >= 'a') {
2018 t = t - 'a' + 10;
2019 } else if (t >= 'A') {
2020 t = t - 'A' + 10;
2021 } else {
2022 t = t - '0';
2023 if (t >= b)
2024 error("invalid digit");
2026 n1 = n;
2027 n = n * b + t;
2028 /* detect overflow */
2029 if (n < n1)
2030 error("integer constant overflow");
2033 /* XXX: not exactly ANSI compliant */
2034 if ((n & 0xffffffff00000000LL) != 0) {
2035 if ((n >> 63) != 0)
2036 tok = TOK_CULLONG;
2037 else
2038 tok = TOK_CLLONG;
2039 } else if (n > 0x7fffffff) {
2040 tok = TOK_CUINT;
2041 } else {
2042 tok = TOK_CINT;
2044 lcount = 0;
2045 for(;;) {
2046 t = toup(ch);
2047 if (t == 'L') {
2048 if (lcount >= 2)
2049 error("three 'l' in integer constant");
2050 lcount++;
2051 if (lcount == 2) {
2052 if (tok == TOK_CINT)
2053 tok = TOK_CLLONG;
2054 else if (tok == TOK_CUINT)
2055 tok = TOK_CULLONG;
2057 cinp();
2058 } else if (t == 'U') {
2059 if (tok == TOK_CINT)
2060 tok = TOK_CUINT;
2061 else if (tok == TOK_CLLONG)
2062 tok = TOK_CULLONG;
2063 cinp();
2064 } else {
2065 break;
2068 if (tok == TOK_CINT || tok == TOK_CUINT)
2069 tokc.ui = n;
2070 else
2071 tokc.ull = n;
2076 /* return next token without macro substitution */
2077 void next_nomacro1(void)
2079 int b;
2080 char *q;
2081 TokenSym *ts;
2083 /* skip spaces */
2084 while(1) {
2085 while (ch == '\n') {
2086 cinp();
2087 while (ch == ' ' || ch == '\t')
2088 cinp();
2089 if (ch == '#') {
2090 /* preprocessor command if # at start of line after
2091 spaces */
2092 preprocess();
2095 if (ch != ' ' && ch != '\t' && ch != '\f')
2096 break;
2097 cinp();
2099 if (isid(ch)) {
2100 q = token_buf;
2101 *q++ = ch;
2102 cinp();
2103 if (q[-1] == 'L') {
2104 if (ch == '\'') {
2105 tok = TOK_LCHAR;
2106 goto char_const;
2108 if (ch == '\"') {
2109 tok = TOK_LSTR;
2110 goto str_const;
2113 while (isid(ch) || isnum(ch)) {
2114 if (q >= token_buf + STRING_MAX_SIZE)
2115 error("ident too long");
2116 *q++ = ch;
2117 cinp();
2119 *q = '\0';
2120 ts = tok_alloc(token_buf, q - token_buf);
2121 tok = ts->tok;
2122 } else if (isnum(ch) || ch == '.') {
2123 parse_number();
2124 } else if (ch == '\'') {
2125 tok = TOK_CCHAR;
2126 char_const:
2127 minp();
2128 tokc.i = getq();
2129 if (ch != '\'')
2130 expect("\'");
2131 minp();
2132 } else if (ch == '\"') {
2133 tok = TOK_STR;
2134 str_const:
2135 minp();
2136 q = token_buf;
2137 while (ch != '\"') {
2138 b = getq();
2139 if (ch == -1)
2140 error("unterminated string");
2141 if (q >= token_buf + STRING_MAX_SIZE)
2142 error("string too long");
2143 *q++ = b;
2145 *q = '\0';
2146 tokc.ts = tok_alloc(token_buf, q - token_buf);
2147 minp();
2148 } else {
2149 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2150 /* two chars */
2151 tok = ch;
2152 cinp();
2153 while (*q) {
2154 if (*q == tok && q[1] == ch) {
2155 cinp();
2156 tok = q[2] & 0xff;
2157 /* three chars tests */
2158 if (tok == TOK_SHL || tok == TOK_SAR) {
2159 if (ch == '=') {
2160 tok = tok | 0x80;
2161 cinp();
2163 } else if (tok == TOK_DOTS) {
2164 if (ch != '.')
2165 error("parse error");
2166 cinp();
2168 return;
2170 q = q + 3;
2172 /* single char substitutions */
2173 if (tok == '<')
2174 tok = TOK_LT;
2175 else if (tok == '>')
2176 tok = TOK_GT;
2180 /* return next token without macro substitution. Can read input from
2181 macro_ptr buffer */
2182 void next_nomacro()
2184 if (macro_ptr) {
2185 redo:
2186 tok = *macro_ptr;
2187 if (tok) {
2188 tok = tok_get(&macro_ptr, &tokc);
2189 if (tok == TOK_LINENUM) {
2190 file->line_num = tokc.i;
2191 goto redo;
2194 } else {
2195 next_nomacro1();
2199 /* substitute args in macro_str and return allocated string */
2200 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2202 int *st, last_tok, t, notfirst;
2203 Sym *s;
2204 TokenSym *ts;
2205 CValue cval;
2206 TokenString str;
2208 tok_str_new(&str);
2209 last_tok = 0;
2210 while(1) {
2211 t = tok_get(&macro_str, &cval);
2212 if (!t)
2213 break;
2214 if (t == '#') {
2215 /* stringize */
2216 t = tok_get(&macro_str, &cval);
2217 if (!t)
2218 break;
2219 s = sym_find2(args, t);
2220 if (s) {
2221 token_buf[0] = '\0';
2222 st = (int *)s->c;
2223 notfirst = 0;
2224 while (*st) {
2225 if (notfirst)
2226 pstrcat(token_buf, sizeof(token_buf), " ");
2227 t = tok_get(&st, &cval);
2228 pstrcat(token_buf, sizeof(token_buf), get_tok_str(t, &cval));
2229 notfirst = 1;
2231 #ifdef PP_DEBUG
2232 printf("stringize: %s\n", token_buf);
2233 #endif
2234 /* add string */
2235 ts = tok_alloc(token_buf, 0);
2236 cval.ts = ts;
2237 tok_str_add2(&str, TOK_STR, &cval);
2238 } else {
2239 tok_str_add2(&str, t, &cval);
2241 } else if (t >= TOK_IDENT) {
2242 s = sym_find2(args, t);
2243 if (s) {
2244 st = (int *)s->c;
2245 /* if '##' is present before or after, no arg substitution */
2246 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2247 /* special case for var arg macros : ## eats the
2248 ',' if empty VA_ARGS riable. */
2249 /* XXX: test of the ',' is not 100%
2250 reliable. should fix it to avoid security
2251 problems */
2252 if (gnu_ext && s->t && *st == 0 &&
2253 last_tok == TOK_TWOSHARPS &&
2254 str.len >= 2&& str.str[str.len - 2] == ',') {
2255 /* suppress ',' '##' */
2256 str.len -= 2;
2257 } else {
2258 while (*st)
2259 tok_str_add(&str, *st++);
2261 } else {
2262 macro_subst(&str, nested_list, st);
2264 } else {
2265 tok_str_add(&str, t);
2267 } else {
2268 tok_str_add2(&str, t, &cval);
2270 last_tok = t;
2272 tok_str_add(&str, 0);
2273 return str.str;
2276 /* handle the '##' operator */
2277 int *macro_twosharps(int *macro_str)
2279 TokenSym *ts;
2280 int *macro_ptr1;
2281 int t;
2282 char *p;
2283 CValue cval;
2284 TokenString macro_str1;
2286 tok_str_new(&macro_str1);
2287 tok = 0;
2288 while (1) {
2289 next_nomacro();
2290 if (tok == 0)
2291 break;
2292 while (*macro_ptr == TOK_TWOSHARPS) {
2293 macro_ptr++;
2294 macro_ptr1 = macro_ptr;
2295 t = *macro_ptr;
2296 if (t) {
2297 t = tok_get(&macro_ptr, &cval);
2298 /* XXX: we handle only most common cases:
2299 ident + ident or ident + number */
2300 if (tok >= TOK_IDENT &&
2301 (t >= TOK_IDENT || t == TOK_CINT)) {
2302 p = get_tok_str(tok, &tokc);
2303 pstrcpy(token_buf, sizeof(token_buf), p);
2304 p = get_tok_str(t, &cval);
2305 pstrcat(token_buf, sizeof(token_buf), p);
2306 ts = tok_alloc(token_buf, 0);
2307 tok = ts->tok; /* modify current token */
2308 } else {
2309 /* cannot merge tokens: skip '##' */
2310 macro_ptr = macro_ptr1;
2311 break;
2315 tok_str_add2(&macro_str1, tok, &tokc);
2317 tok_str_add(&macro_str1, 0);
2318 return macro_str1.str;
2321 /* do macro substitution of macro_str and add result to
2322 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2323 substituted. 'nested_list' is the list of all macros we got inside
2324 to avoid recursing. */
2325 void macro_subst(TokenString *tok_str,
2326 Sym **nested_list, int *macro_str)
2328 Sym *s, *args, *sa, *sa1;
2329 int parlevel, *mstr, t, *saved_macro_ptr;
2330 int mstr_allocated, *macro_str1;
2331 CValue cval;
2332 TokenString str;
2334 saved_macro_ptr = macro_ptr;
2335 macro_ptr = macro_str;
2336 macro_str1 = NULL;
2337 if (macro_str) {
2338 /* first scan for '##' operator handling */
2339 macro_str1 = macro_twosharps(macro_str);
2340 macro_ptr = macro_str1;
2343 while (1) {
2344 next_nomacro();
2345 if (tok == 0)
2346 break;
2347 /* special macros */
2348 if (tok == TOK___LINE__) {
2349 cval.i = file->line_num;
2350 tok_str_add2(tok_str, TOK_CINT, &cval);
2351 } else if (tok == TOK___FILE__) {
2352 cval.ts = tok_alloc(file->filename, 0);
2353 tok_str_add2(tok_str, TOK_STR, &cval);
2354 } else if (tok == TOK___DATE__) {
2355 cval.ts = tok_alloc("Jan 1 1970", 0);
2356 tok_str_add2(tok_str, TOK_STR, &cval);
2357 } else if (tok == TOK___TIME__) {
2358 cval.ts = tok_alloc("00:00:00", 0);
2359 tok_str_add2(tok_str, TOK_STR, &cval);
2360 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
2361 /* if symbol is a macro, prepare substitution */
2362 /* if nested substitution, do nothing */
2363 if (sym_find2(*nested_list, tok))
2364 goto no_subst;
2365 mstr = (int *)s->c;
2366 mstr_allocated = 0;
2367 if (s->t == MACRO_FUNC) {
2368 /* NOTE: we do not use next_nomacro to avoid eating the
2369 next token. XXX: find better solution */
2370 if (macro_ptr) {
2371 t = *macro_ptr;
2372 } else {
2373 while (ch == ' ' || ch == '\t' || ch == '\n')
2374 cinp();
2375 t = ch;
2377 if (t != '(') /* no macro subst */
2378 goto no_subst;
2380 /* argument macro */
2381 next_nomacro();
2382 next_nomacro();
2383 args = NULL;
2384 sa = s->next;
2385 /* NOTE: empty args are allowed, except if no args */
2386 for(;;) {
2387 /* handle '()' case */
2388 if (!args && tok == ')')
2389 break;
2390 if (!sa)
2391 error("macro '%s' used with too many args",
2392 get_tok_str(s->v, 0));
2393 tok_str_new(&str);
2394 parlevel = 0;
2395 /* NOTE: non zero sa->t indicates VA_ARGS */
2396 while ((parlevel > 0 ||
2397 (tok != ')' &&
2398 (tok != ',' || sa->t))) &&
2399 tok != -1) {
2400 if (tok == '(')
2401 parlevel++;
2402 else if (tok == ')')
2403 parlevel--;
2404 tok_str_add2(&str, tok, &tokc);
2405 next_nomacro();
2407 tok_str_add(&str, 0);
2408 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2409 sa = sa->next;
2410 if (tok == ')') {
2411 /* special case for gcc var args: add an empty
2412 var arg argument if it is omitted */
2413 if (sa && sa->t && gnu_ext)
2414 continue;
2415 else
2416 break;
2418 if (tok != ',')
2419 expect(",");
2420 next_nomacro();
2422 if (sa) {
2423 error("macro '%s' used with too few args",
2424 get_tok_str(s->v, 0));
2427 /* now subst each arg */
2428 mstr = macro_arg_subst(nested_list, mstr, args);
2429 /* free memory */
2430 sa = args;
2431 while (sa) {
2432 sa1 = sa->prev;
2433 free((int *)sa->c);
2434 free(sa);
2435 sa = sa1;
2437 mstr_allocated = 1;
2439 sym_push2(nested_list, s->v, 0, 0);
2440 macro_subst(tok_str, nested_list, mstr);
2441 /* pop nested defined symbol */
2442 sa1 = *nested_list;
2443 *nested_list = sa1->prev;
2444 free(sa1);
2445 if (mstr_allocated)
2446 free(mstr);
2447 } else {
2448 no_subst:
2449 /* no need to add if reading input stream */
2450 if (!macro_str)
2451 return;
2452 tok_str_add2(tok_str, tok, &tokc);
2454 /* only replace one macro while parsing input stream */
2455 if (!macro_str)
2456 return;
2458 macro_ptr = saved_macro_ptr;
2459 if (macro_str1)
2460 free(macro_str1);
2463 /* return next token with macro substitution */
2464 void next(void)
2466 Sym *nested_list;
2467 TokenString str;
2469 /* special 'ungettok' case for label parsing */
2470 if (tok1) {
2471 tok = tok1;
2472 tokc = tok1c;
2473 tok1 = 0;
2474 } else {
2475 redo:
2476 if (!macro_ptr) {
2477 /* if not reading from macro substituted string, then try
2478 to substitute */
2479 /* XXX: optimize non macro case */
2480 tok_str_new(&str);
2481 nested_list = NULL;
2482 macro_subst(&str, &nested_list, NULL);
2483 if (str.str) {
2484 tok_str_add(&str, 0);
2485 macro_ptr = str.str;
2486 macro_ptr_allocated = str.str;
2487 goto redo;
2489 if (tok == 0)
2490 goto redo;
2491 } else {
2492 next_nomacro();
2493 if (tok == 0) {
2494 /* end of macro string: free it */
2495 free(macro_ptr_allocated);
2496 macro_ptr = NULL;
2497 goto redo;
2501 #if defined(DEBUG)
2502 printf("token = %s\n", get_tok_str(tok, tokc));
2503 #endif
2506 void swap(int *p, int *q)
2508 int t;
2509 t = *p;
2510 *p = *q;
2511 *q = t;
2514 void vsetc(int t, int r, CValue *vc)
2516 if (vtop >= vstack + VSTACK_SIZE)
2517 error("memory full");
2518 /* cannot let cpu flags if other instruction are generated */
2519 /* XXX: VT_JMP test too ? */
2520 if ((vtop->r & VT_VALMASK) == VT_CMP)
2521 gv(RC_INT);
2522 vtop++;
2523 vtop->t = t;
2524 vtop->r = r;
2525 vtop->r2 = VT_CONST;
2526 vtop->c = *vc;
2529 /* push integer constant */
2530 void vpushi(int v)
2532 CValue cval;
2533 cval.i = v;
2534 vsetc(VT_INT, VT_CONST, &cval);
2537 /* push a reference to a section offset by adding a dummy symbol */
2538 void vpush_ref(int t, Section *sec, unsigned long offset)
2540 int v;
2541 Sym *sym;
2542 CValue cval;
2544 v = anon_sym++;
2545 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2546 sym->r = VT_CONST | VT_SYM;
2547 put_extern_sym(sym, sec, offset);
2548 cval.sym = sym;
2549 vsetc(t, VT_CONST | VT_SYM, &cval);
2552 void vset(int t, int r, int v)
2554 CValue cval;
2556 cval.i = v;
2557 vsetc(t, r, &cval);
2560 void vswap(void)
2562 SValue tmp;
2564 tmp = vtop[0];
2565 vtop[0] = vtop[-1];
2566 vtop[-1] = tmp;
2569 void vpushv(SValue *v)
2571 if (vtop >= vstack + VSTACK_SIZE)
2572 error("memory full");
2573 vtop++;
2574 *vtop = *v;
2577 void vdup(void)
2579 vpushv(vtop);
2582 /* save r to the memory stack, and mark it as being free */
2583 void save_reg(int r)
2585 int l, i, saved, t, size, align;
2586 SValue *p, sv;
2588 /* modify all stack values */
2589 saved = 0;
2590 l = 0;
2591 for(p=vstack;p<=vtop;p++) {
2592 i = p->r & VT_VALMASK;
2593 if ((p->r & VT_VALMASK) == r ||
2594 (p->r2 & VT_VALMASK) == r) {
2595 /* must save value on stack if not already done */
2596 if (!saved) {
2597 /* store register in the stack */
2598 t = p->t;
2599 if ((p->r & VT_LVAL) ||
2600 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
2601 t = VT_INT;
2602 size = type_size(t, &align);
2603 loc = (loc - size) & -align;
2604 sv.t = t;
2605 sv.r = VT_LOCAL | VT_LVAL;
2606 sv.c.ul = loc;
2607 store(r, &sv);
2608 #ifdef TCC_TARGET_I386
2609 /* x86 specific: need to pop fp register ST0 if saved */
2610 if (r == REG_ST0) {
2611 o(0xd9dd); /* fstp %st(1) */
2613 #endif
2614 /* special long long case */
2615 if ((t & VT_BTYPE) == VT_LLONG) {
2616 sv.c.ul += 4;
2617 store(p->r2, &sv);
2619 l = loc;
2620 saved = 1;
2622 /* mark that stack entry as being saved on the stack */
2623 if (p->r & VT_LVAL)
2624 t = VT_LLOCAL;
2625 else
2626 t = VT_LOCAL;
2627 p->r = VT_LVAL | t;
2628 p->r2 = VT_CONST;
2629 p->c.ul = l;
2634 /* find a free register of class 'rc'. If none, save one register */
2635 int get_reg(int rc)
2637 int r;
2638 SValue *p;
2640 /* find a free register */
2641 for(r=0;r<NB_REGS;r++) {
2642 if (reg_classes[r] & rc) {
2643 for(p=vstack;p<=vtop;p++) {
2644 if ((p->r & VT_VALMASK) == r ||
2645 (p->r2 & VT_VALMASK) == r)
2646 goto notfound;
2648 return r;
2650 notfound: ;
2653 /* no register left : free the first one on the stack (VERY
2654 IMPORTANT to start from the bottom to ensure that we don't
2655 spill registers used in gen_opi()) */
2656 for(p=vstack;p<=vtop;p++) {
2657 r = p->r & VT_VALMASK;
2658 if (r < VT_CONST && (reg_classes[r] & rc)) {
2659 save_reg(r);
2660 break;
2663 return r;
2666 /* save registers up to (vtop - n) stack entry */
2667 void save_regs(int n)
2669 int r;
2670 SValue *p, *p1;
2671 p1 = vtop - n;
2672 for(p = vstack;p <= p1; p++) {
2673 r = p->r & VT_VALMASK;
2674 if (r < VT_CONST) {
2675 save_reg(r);
2680 /* move register 's' to 'r', and flush previous value of r to memory
2681 if needed */
2682 void move_reg(int r, int s)
2684 SValue sv;
2686 if (r != s) {
2687 save_reg(r);
2688 sv.t = VT_INT;
2689 sv.r = s;
2690 sv.c.ul = 0;
2691 load(r, &sv);
2695 /* get address of vtop (vtop MUST BE an lvalue) */
2696 void gaddrof(void)
2698 vtop->r &= ~VT_LVAL;
2699 /* tricky: if saved lvalue, then we can go back to lvalue */
2700 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
2701 vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
2704 #ifdef CONFIG_TCC_BCHECK
2705 /* generate lvalue bound code */
2706 void gbound(void)
2708 int lval_type;
2710 vtop->r &= ~VT_MUSTBOUND;
2711 /* if lvalue, then use checking code before dereferencing */
2712 if (vtop->r & VT_LVAL) {
2713 /* if not VT_BOUNDED value, then make one */
2714 if (!(vtop->r & VT_BOUNDED)) {
2715 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
2716 gaddrof();
2717 vpushi(0);
2718 gen_bounded_ptr_add();
2719 vtop->r |= lval_type;
2721 /* then check for dereferencing */
2722 gen_bounded_ptr_deref();
2725 #endif
2727 /* store vtop a register belonging to class 'rc'. lvalues are
2728 converted to values. Cannot be used if cannot be converted to
2729 register value (such as structures). */
2730 int gv(int rc)
2732 int r, r2, rc2, bit_pos, bit_size, size, align, i, data_offset;
2733 unsigned long long ll;
2735 /* NOTE: get_reg can modify vstack[] */
2736 if (vtop->t & VT_BITFIELD) {
2737 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
2738 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2739 /* remove bit field info to avoid loops */
2740 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2741 /* generate shifts */
2742 vpushi(32 - (bit_pos + bit_size));
2743 gen_op(TOK_SHL);
2744 vpushi(32 - bit_size);
2745 /* NOTE: transformed to SHR if unsigned */
2746 gen_op(TOK_SAR);
2747 r = gv(rc);
2748 } else {
2749 if (is_float(vtop->t) &&
2750 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2751 int v;
2752 Sym *sym;
2754 /* XXX: unify with initializers handling ? */
2755 /* CPUs usually cannot use float constants, so we store them
2756 generically in data segment */
2757 size = type_size(vtop->t, &align);
2758 data_offset = data_section->data_ptr - data_section->data;
2759 data_offset = (data_offset + align - 1) & -align;
2760 /* XXX: not portable yet */
2761 size = size >> 2;
2762 for(i=0;i<size;i++)
2763 ((int *)(data_section->data + data_offset))[i] = vtop->c.tab[i];
2765 v = anon_sym++;
2766 sym = sym_push1(&global_stack, v, vtop->t | VT_STATIC, 0);
2767 sym->r = VT_CONST | VT_SYM;
2768 put_extern_sym(sym, data_section, data_offset);
2770 vtop->r |= VT_LVAL | VT_SYM;
2771 vtop->c.sym = sym;
2772 data_offset += size << 2;
2773 data_section->data_ptr = data_section->data + data_offset;
2775 #ifdef CONFIG_TCC_BCHECK
2776 if (vtop->r & VT_MUSTBOUND)
2777 gbound();
2778 #endif
2780 r = vtop->r & VT_VALMASK;
2781 /* need to reload if:
2782 - constant
2783 - lvalue (need to dereference pointer)
2784 - already a register, but not in the right class */
2785 if (r >= VT_CONST ||
2786 (vtop->r & VT_LVAL) ||
2787 !(reg_classes[r] & rc) ||
2788 ((vtop->t & VT_BTYPE) == VT_LLONG &&
2789 !(reg_classes[vtop->r2] & rc))) {
2790 r = get_reg(rc);
2791 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
2792 /* two register type load : expand to two words
2793 temporarily */
2794 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2795 /* load constant */
2796 ll = vtop->c.ull;
2797 vtop->c.ui = ll; /* first word */
2798 load(r, vtop);
2799 vtop->r = r; /* save register value */
2800 vpushi(ll >> 32); /* second word */
2801 } else if (r >= VT_CONST ||
2802 (vtop->r & VT_LVAL)) {
2803 /* load from memory */
2804 load(r, vtop);
2805 vdup();
2806 vtop[-1].r = r; /* save register value */
2807 /* increment pointer to get second word */
2808 vtop->t = VT_INT;
2809 gaddrof();
2810 vpushi(4);
2811 gen_op('+');
2812 vtop->r |= VT_LVAL;
2813 } else {
2814 /* move registers */
2815 load(r, vtop);
2816 vdup();
2817 vtop[-1].r = r; /* save register value */
2818 vtop->r = vtop[-1].r2;
2820 /* allocate second register */
2821 rc2 = RC_INT;
2822 if (rc == RC_IRET)
2823 rc2 = RC_LRET;
2824 r2 = get_reg(rc2);
2825 load(r2, vtop);
2826 vpop();
2827 /* write second register */
2828 vtop->r2 = r2;
2829 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
2830 int t1, t;
2831 /* lvalue of scalar type : need to use lvalue type
2832 because of possible cast */
2833 t = vtop->t;
2834 t1 = t;
2835 /* compute memory access type */
2836 if (vtop->r & VT_LVAL_BYTE)
2837 t = VT_BYTE;
2838 else if (vtop->r & VT_LVAL_SHORT)
2839 t = VT_SHORT;
2840 if (vtop->r & VT_LVAL_UNSIGNED)
2841 t |= VT_UNSIGNED;
2842 vtop->t = t;
2843 load(r, vtop);
2844 /* restore wanted type */
2845 vtop->t = t1;
2846 } else {
2847 /* one register type load */
2848 load(r, vtop);
2851 vtop->r = r;
2853 return r;
2856 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2857 void gv2(int rc1, int rc2)
2859 /* generate more generic register first */
2860 if (rc1 <= rc2) {
2861 vswap();
2862 gv(rc1);
2863 vswap();
2864 gv(rc2);
2865 /* test if reload is needed for first register */
2866 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2867 vswap();
2868 gv(rc1);
2869 vswap();
2871 } else {
2872 gv(rc2);
2873 vswap();
2874 gv(rc1);
2875 vswap();
2876 /* test if reload is needed for first register */
2877 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2878 gv(rc2);
2883 /* expand long long on stack in two int registers */
2884 void lexpand(void)
2886 int u;
2888 u = vtop->t & VT_UNSIGNED;
2889 gv(RC_INT);
2890 vdup();
2891 vtop[0].r = vtop[-1].r2;
2892 vtop[0].r2 = VT_CONST;
2893 vtop[-1].r2 = VT_CONST;
2894 vtop[0].t = VT_INT | u;
2895 vtop[-1].t = VT_INT | u;
2898 /* build a long long from two ints */
2899 void lbuild(int t)
2901 gv2(RC_INT, RC_INT);
2902 vtop[-1].r2 = vtop[0].r;
2903 vtop[-1].t = t;
2904 vpop();
2907 /* rotate n first stack elements to the bottom */
2908 void vrotb(int n)
2910 int i;
2911 SValue tmp;
2913 tmp = vtop[-n + 1];
2914 for(i=-n+1;i!=0;i++)
2915 vtop[i] = vtop[i+1];
2916 vtop[0] = tmp;
2919 /* pop stack value */
2920 void vpop(void)
2922 int v;
2923 v = vtop->r & VT_VALMASK;
2924 #ifdef TCC_TARGET_I386
2925 /* for x86, we need to pop the FP stack */
2926 if (v == REG_ST0) {
2927 o(0xd9dd); /* fstp %st(1) */
2928 } else
2929 #endif
2930 if (v == VT_JMP || v == VT_JMPI) {
2931 /* need to put correct jump if && or || without test */
2932 gsym(vtop->c.ul);
2934 vtop--;
2937 /* convert stack entry to register and duplicate its value in another
2938 register */
2939 void gv_dup(void)
2941 int rc, t, r, r1;
2942 SValue sv;
2944 t = vtop->t;
2945 if ((t & VT_BTYPE) == VT_LLONG) {
2946 lexpand();
2947 gv_dup();
2948 vswap();
2949 vrotb(3);
2950 gv_dup();
2951 vrotb(4);
2952 /* stack: H L L1 H1 */
2953 lbuild(t);
2954 vrotb(3);
2955 vrotb(3);
2956 vswap();
2957 lbuild(t);
2958 vswap();
2959 } else {
2960 /* duplicate value */
2961 rc = RC_INT;
2962 sv.t = VT_INT;
2963 if (is_float(t)) {
2964 rc = RC_FLOAT;
2965 sv.t = t;
2967 r = gv(rc);
2968 r1 = get_reg(rc);
2969 sv.r = r;
2970 sv.c.ul = 0;
2971 load(r1, &sv); /* move r to r1 */
2972 vdup();
2973 /* duplicates value */
2974 vtop->r = r1;
2978 /* generate CPU independent (unsigned) long long operations */
2979 void gen_opl(int op)
2981 int t, a, b, op1, c, i;
2982 void *func;
2983 GFuncContext gf;
2984 SValue tmp;
2986 switch(op) {
2987 case '/':
2988 case TOK_PDIV:
2989 func = __divll;
2990 goto gen_func;
2991 case TOK_UDIV:
2992 func = __divull;
2993 goto gen_func;
2994 case '%':
2995 func = __modll;
2996 goto gen_func;
2997 case TOK_UMOD:
2998 func = __modull;
2999 gen_func:
3000 /* call generic long long function */
3001 gfunc_start(&gf, FUNC_CDECL);
3002 gfunc_param(&gf);
3003 gfunc_param(&gf);
3004 vpushi((int)func);
3005 gfunc_call(&gf);
3006 vpushi(0);
3007 vtop->r = REG_IRET;
3008 vtop->r2 = REG_LRET;
3009 break;
3010 case '^':
3011 case '&':
3012 case '|':
3013 case '*':
3014 case '+':
3015 case '-':
3016 t = vtop->t;
3017 vswap();
3018 lexpand();
3019 vrotb(3);
3020 lexpand();
3021 /* stack: L1 H1 L2 H2 */
3022 tmp = vtop[0];
3023 vtop[0] = vtop[-3];
3024 vtop[-3] = tmp;
3025 tmp = vtop[-2];
3026 vtop[-2] = vtop[-3];
3027 vtop[-3] = tmp;
3028 vswap();
3029 /* stack: H1 H2 L1 L2 */
3030 if (op == '*') {
3031 vpushv(vtop - 1);
3032 vpushv(vtop - 1);
3033 gen_op(TOK_UMULL);
3034 lexpand();
3035 /* stack: H1 H2 L1 L2 ML MH */
3036 for(i=0;i<4;i++)
3037 vrotb(6);
3038 /* stack: ML MH H1 H2 L1 L2 */
3039 tmp = vtop[0];
3040 vtop[0] = vtop[-2];
3041 vtop[-2] = tmp;
3042 /* stack: ML MH H1 L2 H2 L1 */
3043 gen_op('*');
3044 vrotb(3);
3045 vrotb(3);
3046 gen_op('*');
3047 /* stack: ML MH M1 M2 */
3048 gen_op('+');
3049 gen_op('+');
3050 } else if (op == '+' || op == '-') {
3051 /* XXX: add non carry method too (for MIPS or alpha) */
3052 if (op == '+')
3053 op1 = TOK_ADDC1;
3054 else
3055 op1 = TOK_SUBC1;
3056 gen_op(op1);
3057 /* stack: H1 H2 (L1 op L2) */
3058 vrotb(3);
3059 vrotb(3);
3060 gen_op(op1 + 1); /* TOK_xxxC2 */
3061 } else {
3062 gen_op(op);
3063 /* stack: H1 H2 (L1 op L2) */
3064 vrotb(3);
3065 vrotb(3);
3066 /* stack: (L1 op L2) H1 H2 */
3067 gen_op(op);
3068 /* stack: (L1 op L2) (H1 op H2) */
3070 /* stack: L H */
3071 lbuild(t);
3072 break;
3073 case TOK_SAR:
3074 case TOK_SHR:
3075 case TOK_SHL:
3076 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3077 t = vtop[-1].t;
3078 vswap();
3079 lexpand();
3080 vrotb(3);
3081 /* stack: L H shift */
3082 c = (int)vtop->c.i;
3083 /* constant: simpler */
3084 /* NOTE: all comments are for SHL. the other cases are
3085 done by swaping words */
3086 vpop();
3087 if (op != TOK_SHL)
3088 vswap();
3089 if (c >= 32) {
3090 /* stack: L H */
3091 vpop();
3092 if (c > 32) {
3093 vpushi(c - 32);
3094 gen_op(op);
3096 if (op != TOK_SAR) {
3097 vpushi(0);
3098 } else {
3099 gv_dup();
3100 vpushi(31);
3101 gen_op(TOK_SAR);
3103 vswap();
3104 } else {
3105 vswap();
3106 gv_dup();
3107 /* stack: H L L */
3108 vpushi(c);
3109 gen_op(op);
3110 vswap();
3111 vpushi(32 - c);
3112 if (op == TOK_SHL)
3113 gen_op(TOK_SHR);
3114 else
3115 gen_op(TOK_SHL);
3116 vrotb(3);
3117 /* stack: L L H */
3118 vpushi(c);
3119 gen_op(op);
3120 gen_op('|');
3122 if (op != TOK_SHL)
3123 vswap();
3124 lbuild(t);
3125 } else {
3126 /* XXX: should provide a faster fallback on x86 ? */
3127 switch(op) {
3128 case TOK_SAR:
3129 func = __sardi3;
3130 goto gen_func;
3131 case TOK_SHR:
3132 func = __shrdi3;
3133 goto gen_func;
3134 case TOK_SHL:
3135 func = __shldi3;
3136 goto gen_func;
3139 break;
3140 default:
3141 /* compare operations */
3142 t = vtop->t;
3143 vswap();
3144 lexpand();
3145 vrotb(3);
3146 lexpand();
3147 /* stack: L1 H1 L2 H2 */
3148 tmp = vtop[-1];
3149 vtop[-1] = vtop[-2];
3150 vtop[-2] = tmp;
3151 /* stack: L1 L2 H1 H2 */
3152 /* compare high */
3153 op1 = op;
3154 /* when values are equal, we need to compare low words. since
3155 the jump is inverted, we invert the test too. */
3156 if (op1 == TOK_LT)
3157 op1 = TOK_LE;
3158 else if (op1 == TOK_GT)
3159 op1 = TOK_GE;
3160 else if (op1 == TOK_ULT)
3161 op1 = TOK_ULE;
3162 else if (op1 == TOK_UGT)
3163 op1 = TOK_UGE;
3164 a = 0;
3165 b = 0;
3166 gen_op(op1);
3167 if (op1 != TOK_NE) {
3168 a = gtst(1, 0);
3170 if (op != TOK_EQ) {
3171 /* generate non equal test */
3172 /* XXX: NOT PORTABLE yet */
3173 if (a == 0) {
3174 b = gtst(0, 0);
3175 } else {
3176 #ifdef TCC_TARGET_I386
3177 b = psym(0x850f, 0);
3178 #else
3179 error("not implemented");
3180 #endif
3183 /* compare low */
3184 gen_op(op);
3185 a = gtst(1, a);
3186 gsym(b);
3187 vset(VT_INT, VT_JMPI, a);
3188 break;
3192 /* handle integer constant optimizations and various machine
3193 independant opt */
3194 void gen_opic(int op)
3196 int fc, c1, c2, n;
3197 SValue *v1, *v2;
3199 v1 = vtop - 1;
3200 v2 = vtop;
3201 /* currently, we cannot do computations with forward symbols */
3202 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3203 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3204 if (c1 && c2) {
3205 fc = v2->c.i;
3206 switch(op) {
3207 case '+': v1->c.i += fc; break;
3208 case '-': v1->c.i -= fc; break;
3209 case '&': v1->c.i &= fc; break;
3210 case '^': v1->c.i ^= fc; break;
3211 case '|': v1->c.i |= fc; break;
3212 case '*': v1->c.i *= fc; break;
3214 case TOK_PDIV:
3215 case '/':
3216 case '%':
3217 case TOK_UDIV:
3218 case TOK_UMOD:
3219 /* if division by zero, generate explicit division */
3220 if (fc == 0) {
3221 if (const_wanted)
3222 error("division by zero in constant");
3223 goto general_case;
3225 switch(op) {
3226 default: v1->c.i /= fc; break;
3227 case '%': v1->c.i %= fc; break;
3228 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3229 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3231 break;
3232 case TOK_SHL: v1->c.i <<= fc; break;
3233 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3234 case TOK_SAR: v1->c.i >>= fc; break;
3235 /* tests */
3236 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3237 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3238 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3239 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3240 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3241 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3242 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3243 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3244 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3245 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3246 /* logical */
3247 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3248 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3249 default:
3250 goto general_case;
3252 vtop--;
3253 } else {
3254 /* if commutative ops, put c2 as constant */
3255 if (c1 && (op == '+' || op == '&' || op == '^' ||
3256 op == '|' || op == '*')) {
3257 vswap();
3258 swap(&c1, &c2);
3260 fc = vtop->c.i;
3261 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3262 op == TOK_PDIV) &&
3263 fc == 1) ||
3264 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3265 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3266 fc == 0) ||
3267 (op == '&' &&
3268 fc == -1))) {
3269 /* nothing to do */
3270 vtop--;
3271 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3272 /* try to use shifts instead of muls or divs */
3273 if (fc > 0 && (fc & (fc - 1)) == 0) {
3274 n = -1;
3275 while (fc) {
3276 fc >>= 1;
3277 n++;
3279 vtop->c.i = n;
3280 if (op == '*')
3281 op = TOK_SHL;
3282 else if (op == TOK_PDIV)
3283 op = TOK_SAR;
3284 else
3285 op = TOK_SHR;
3287 goto general_case;
3288 } else {
3289 general_case:
3290 /* call low level op generator */
3291 gen_opi(op);
3296 /* generate a floating point operation with constant propagation */
3297 void gen_opif(int op)
3299 int c1, c2;
3300 SValue *v1, *v2;
3301 long double f1, f2;
3303 v1 = vtop - 1;
3304 v2 = vtop;
3305 /* currently, we cannot do computations with forward symbols */
3306 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3307 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3308 if (c1 && c2) {
3309 if (v1->t == VT_FLOAT) {
3310 f1 = v1->c.f;
3311 f2 = v2->c.f;
3312 } else if (v1->t == VT_DOUBLE) {
3313 f1 = v1->c.d;
3314 f2 = v2->c.d;
3315 } else {
3316 f1 = v1->c.ld;
3317 f2 = v2->c.ld;
3320 /* NOTE: we only do constant propagation if finite number (not
3321 NaN or infinity) (ANSI spec) */
3322 if (!ieee_finite(f1) || !ieee_finite(f2))
3323 goto general_case;
3325 switch(op) {
3326 case '+': f1 += f2; break;
3327 case '-': f1 -= f2; break;
3328 case '*': f1 *= f2; break;
3329 case '/':
3330 if (f2 == 0.0) {
3331 if (const_wanted)
3332 error("division by zero in constant");
3333 goto general_case;
3335 f1 /= f2;
3336 break;
3337 /* XXX: also handles tests ? */
3338 default:
3339 goto general_case;
3341 /* XXX: overflow test ? */
3342 if (v1->t == VT_FLOAT) {
3343 v1->c.f = f1;
3344 } else if (v1->t == VT_DOUBLE) {
3345 v1->c.d = f1;
3346 } else {
3347 v1->c.ld = f1;
3349 vtop--;
3350 } else {
3351 general_case:
3352 gen_opf(op);
3357 int pointed_size(int t)
3359 return type_size(pointed_type(t), &t);
3362 #if 0
3363 void check_pointer_types(SValue *p1, SValue *p2)
3365 char buf1[256], buf2[256];
3366 int t1, t2;
3367 t1 = p1->t;
3368 t2 = p2->t;
3369 if (!is_compatible_types(t1, t2)) {
3370 type_to_str(buf1, sizeof(buf1), t1, NULL);
3371 type_to_str(buf2, sizeof(buf2), t2, NULL);
3372 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3375 #endif
3377 /* generic gen_op: handles types problems */
3378 void gen_op(int op)
3380 int u, t1, t2, bt1, bt2, t;
3382 t1 = vtop[-1].t;
3383 t2 = vtop[0].t;
3384 bt1 = t1 & VT_BTYPE;
3385 bt2 = t2 & VT_BTYPE;
3387 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3388 /* at least one operand is a pointer */
3389 /* relationnal op: must be both pointers */
3390 if (op >= TOK_ULT && op <= TOK_GT) {
3391 // check_pointer_types(vtop, vtop - 1);
3392 /* pointers are handled are unsigned */
3393 t = VT_INT | VT_UNSIGNED;
3394 goto std_op;
3396 /* if both pointers, then it must be the '-' op */
3397 if ((t1 & VT_BTYPE) == VT_PTR &&
3398 (t2 & VT_BTYPE) == VT_PTR) {
3399 if (op != '-')
3400 error("cannot use pointers here");
3401 // check_pointer_types(vtop - 1, vtop);
3402 /* XXX: check that types are compatible */
3403 u = pointed_size(t1);
3404 gen_opic(op);
3405 /* set to integer type */
3406 vtop->t = VT_INT;
3407 vpushi(u);
3408 gen_op(TOK_PDIV);
3409 } else {
3410 /* exactly one pointer : must be '+' or '-'. */
3411 if (op != '-' && op != '+')
3412 error("cannot use pointers here");
3413 /* Put pointer as first operand */
3414 if ((t2 & VT_BTYPE) == VT_PTR) {
3415 vswap();
3416 swap(&t1, &t2);
3418 /* XXX: cast to int ? (long long case) */
3419 vpushi(pointed_size(vtop[-1].t));
3420 gen_op('*');
3421 #ifdef CONFIG_TCC_BCHECK
3422 /* if evaluating constant expression, no code should be
3423 generated, so no bound check */
3424 if (do_bounds_check && !const_wanted) {
3425 /* if bounded pointers, we generate a special code to
3426 test bounds */
3427 if (op == '-') {
3428 vpushi(0);
3429 vswap();
3430 gen_op('-');
3432 gen_bounded_ptr_add();
3433 } else
3434 #endif
3436 gen_opic(op);
3438 /* put again type if gen_opic() swaped operands */
3439 vtop->t = t1;
3441 } else if (is_float(bt1) || is_float(bt2)) {
3442 /* compute bigger type and do implicit casts */
3443 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3444 t = VT_LDOUBLE;
3445 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3446 t = VT_DOUBLE;
3447 } else {
3448 t = VT_FLOAT;
3450 /* floats can only be used for a few operations */
3451 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3452 (op < TOK_ULT || op > TOK_GT))
3453 error("invalid operands for binary operation");
3454 goto std_op;
3455 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3456 /* cast to biggest op */
3457 t = VT_LLONG;
3458 /* convert to unsigned if it does not fit in a long long */
3459 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3460 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3461 t |= VT_UNSIGNED;
3462 goto std_op;
3463 } else {
3464 /* integer operations */
3465 t = VT_INT;
3466 /* convert to unsigned if it does not fit in an integer */
3467 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3468 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3469 t |= VT_UNSIGNED;
3470 std_op:
3471 /* XXX: currently, some unsigned operations are explicit, so
3472 we modify them here */
3473 if (t & VT_UNSIGNED) {
3474 if (op == TOK_SAR)
3475 op = TOK_SHR;
3476 else if (op == '/')
3477 op = TOK_UDIV;
3478 else if (op == '%')
3479 op = TOK_UMOD;
3480 else if (op == TOK_LT)
3481 op = TOK_ULT;
3482 else if (op == TOK_GT)
3483 op = TOK_UGT;
3484 else if (op == TOK_LE)
3485 op = TOK_ULE;
3486 else if (op == TOK_GE)
3487 op = TOK_UGE;
3489 vswap();
3490 gen_cast(t);
3491 vswap();
3492 /* special case for shifts and long long: we keep the shift as
3493 an integer */
3494 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3495 gen_cast(VT_INT);
3496 else
3497 gen_cast(t);
3498 if (is_float(t))
3499 gen_opif(op);
3500 else if ((t & VT_BTYPE) == VT_LLONG)
3501 gen_opl(op);
3502 else
3503 gen_opic(op);
3504 if (op >= TOK_ULT && op <= TOK_GT) {
3505 /* relationnal op: the result is an int */
3506 vtop->t = VT_INT;
3507 } else {
3508 vtop->t = t;
3513 /* generic itof for unsigned long long case */
3514 void gen_cvt_itof1(int t)
3516 GFuncContext gf;
3518 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3519 (VT_LLONG | VT_UNSIGNED)) {
3521 gfunc_start(&gf, FUNC_CDECL);
3522 gfunc_param(&gf);
3523 if (t == VT_FLOAT)
3524 vpushi((int)&__ulltof);
3525 else if (t == VT_DOUBLE)
3526 vpushi((int)&__ulltod);
3527 else
3528 vpushi((int)&__ulltold);
3529 gfunc_call(&gf);
3530 vpushi(0);
3531 vtop->r = REG_FRET;
3532 } else {
3533 gen_cvt_itof(t);
3537 /* generic ftoi for unsigned long long case */
3538 void gen_cvt_ftoi1(int t)
3540 GFuncContext gf;
3541 int st;
3543 if (t == (VT_LLONG | VT_UNSIGNED)) {
3544 /* not handled natively */
3545 gfunc_start(&gf, FUNC_CDECL);
3546 st = vtop->t & VT_BTYPE;
3547 gfunc_param(&gf);
3548 if (st == VT_FLOAT)
3549 vpushi((int)&__ftoull);
3550 else if (st == VT_DOUBLE)
3551 vpushi((int)&__dtoull);
3552 else
3553 vpushi((int)&__ldtoull);
3554 gfunc_call(&gf);
3555 vpushi(0);
3556 vtop->r = REG_IRET;
3557 vtop->r2 = REG_LRET;
3558 } else {
3559 gen_cvt_ftoi(t);
3563 /* force char or short cast */
3564 void force_charshort_cast(int t)
3566 int bits, dbt;
3567 dbt = t & VT_BTYPE;
3568 /* XXX: add optimization if lvalue : just change type and offset */
3569 if (dbt == VT_BYTE)
3570 bits = 8;
3571 else
3572 bits = 16;
3573 if (t & VT_UNSIGNED) {
3574 vpushi((1 << bits) - 1);
3575 gen_op('&');
3576 } else {
3577 bits = 32 - bits;
3578 vpushi(bits);
3579 gen_op(TOK_SHL);
3580 vpushi(bits);
3581 gen_op(TOK_SAR);
3585 /* cast 'vtop' to 't' type */
3586 void gen_cast(int t)
3588 int sbt, dbt, sf, df, c;
3590 /* special delayed cast for char/short */
3591 /* XXX: in some cases (multiple cascaded casts), it may still
3592 be incorrect */
3593 if (vtop->r & VT_MUSTCAST) {
3594 vtop->r &= ~VT_MUSTCAST;
3595 force_charshort_cast(vtop->t);
3598 dbt = t & (VT_BTYPE | VT_UNSIGNED);
3599 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
3601 if (sbt != dbt) {
3602 sf = is_float(sbt);
3603 df = is_float(dbt);
3604 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3605 if (sf && df) {
3606 /* convert from fp to fp */
3607 if (c) {
3608 /* constant case: we can do it now */
3609 /* XXX: in ISOC, cannot do it if error in convert */
3610 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
3611 vtop->c.f = (float)vtop->c.d;
3612 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
3613 vtop->c.f = (float)vtop->c.ld;
3614 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
3615 vtop->c.d = (double)vtop->c.f;
3616 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
3617 vtop->c.d = (double)vtop->c.ld;
3618 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
3619 vtop->c.ld = (long double)vtop->c.f;
3620 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
3621 vtop->c.ld = (long double)vtop->c.d;
3622 } else {
3623 /* non constant case: generate code */
3624 gen_cvt_ftof(dbt);
3626 } else if (df) {
3627 /* convert int to fp */
3628 if (c) {
3629 switch(sbt) {
3630 case VT_LLONG | VT_UNSIGNED:
3631 case VT_LLONG:
3632 /* XXX: add const cases for long long */
3633 goto do_itof;
3634 case VT_INT | VT_UNSIGNED:
3635 switch(dbt) {
3636 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
3637 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
3638 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
3640 break;
3641 default:
3642 switch(dbt) {
3643 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
3644 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
3645 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
3647 break;
3649 } else {
3650 do_itof:
3651 gen_cvt_itof1(dbt);
3653 } else if (sf) {
3654 /* convert fp to int */
3655 /* we handle char/short/etc... with generic code */
3656 if (dbt != (VT_INT | VT_UNSIGNED) &&
3657 dbt != (VT_LLONG | VT_UNSIGNED) &&
3658 dbt != VT_LLONG)
3659 dbt = VT_INT;
3660 if (c) {
3661 switch(dbt) {
3662 case VT_LLONG | VT_UNSIGNED:
3663 case VT_LLONG:
3664 /* XXX: add const cases for long long */
3665 goto do_ftoi;
3666 case VT_INT | VT_UNSIGNED:
3667 switch(sbt) {
3668 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
3669 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3670 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3672 break;
3673 default:
3674 /* int case */
3675 switch(sbt) {
3676 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
3677 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
3678 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
3680 break;
3682 } else {
3683 do_ftoi:
3684 gen_cvt_ftoi1(dbt);
3686 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
3687 /* additionnal cast for char/short/bool... */
3688 vtop->t = dbt;
3689 gen_cast(t);
3691 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
3692 if ((sbt & VT_BTYPE) != VT_LLONG) {
3693 /* scalar to long long */
3694 if (c) {
3695 if (sbt == (VT_INT | VT_UNSIGNED))
3696 vtop->c.ll = vtop->c.ui;
3697 else
3698 vtop->c.ll = vtop->c.i;
3699 } else {
3700 /* machine independant conversion */
3701 gv(RC_INT);
3702 /* generate high word */
3703 if (sbt == (VT_INT | VT_UNSIGNED)) {
3704 vpushi(0);
3705 gv(RC_INT);
3706 } else {
3707 gv_dup();
3708 vpushi(31);
3709 gen_op(TOK_SAR);
3711 /* patch second register */
3712 vtop[-1].r2 = vtop->r;
3713 vpop();
3716 } else if (dbt == VT_BOOL) {
3717 /* scalar to bool */
3718 vpushi(0);
3719 gen_op(TOK_NE);
3720 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
3721 (dbt & VT_BTYPE) == VT_SHORT) {
3722 force_charshort_cast(t);
3723 } else if ((dbt & VT_BTYPE) == VT_INT) {
3724 /* scalar to int */
3725 if (sbt == VT_LLONG) {
3726 /* from long long: just take low order word */
3727 lexpand();
3728 vpop();
3730 /* if lvalue and single word type, nothing to do because
3731 the lvalue already contains the real type size (see
3732 VT_LVAL_xxx constants) */
3735 vtop->t = t;
3738 /* return type size. Put alignment at 'a' */
3739 int type_size(int t, int *a)
3741 Sym *s;
3742 int bt;
3744 bt = t & VT_BTYPE;
3745 if (bt == VT_STRUCT) {
3746 /* struct/union */
3747 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3748 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
3749 return s->c;
3750 } else if (bt == VT_PTR) {
3751 if (t & VT_ARRAY) {
3752 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3753 return type_size(s->t, a) * s->c;
3754 } else {
3755 *a = PTR_SIZE;
3756 return PTR_SIZE;
3758 } else if (bt == VT_LDOUBLE) {
3759 *a = LDOUBLE_ALIGN;
3760 return LDOUBLE_SIZE;
3761 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3762 *a = 8;
3763 return 8;
3764 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
3765 *a = 4;
3766 return 4;
3767 } else if (bt == VT_SHORT) {
3768 *a = 2;
3769 return 2;
3770 } else {
3771 /* char, void, function, _Bool */
3772 *a = 1;
3773 return 1;
3777 /* return the pointed type of t */
3778 int pointed_type(int t)
3780 Sym *s;
3781 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3782 return s->t | (t & ~VT_TYPE);
3785 int mk_pointer(int t)
3787 int p;
3788 p = anon_sym++;
3789 sym_push(p, t, 0, -1);
3790 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
3793 int is_compatible_types(int t1, int t2)
3795 Sym *s1, *s2;
3796 int bt1, bt2;
3798 t1 &= VT_TYPE;
3799 t2 &= VT_TYPE;
3800 bt1 = t1 & VT_BTYPE;
3801 bt2 = t2 & VT_BTYPE;
3802 if (bt1 == VT_PTR) {
3803 t1 = pointed_type(t1);
3804 /* if function, then convert implicitely to function pointer */
3805 if (bt2 != VT_FUNC) {
3806 if (bt2 != VT_PTR)
3807 return 0;
3808 t2 = pointed_type(t2);
3810 /* void matches everything */
3811 t1 &= VT_TYPE;
3812 t2 &= VT_TYPE;
3813 if (t1 == VT_VOID || t2 == VT_VOID)
3814 return 1;
3815 return is_compatible_types(t1, t2);
3816 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3817 return (t2 == t1);
3818 } else if (bt1 == VT_FUNC) {
3819 if (bt2 != VT_FUNC)
3820 return 0;
3821 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
3822 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
3823 if (!is_compatible_types(s1->t, s2->t))
3824 return 0;
3825 /* XXX: not complete */
3826 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
3827 return 1;
3828 if (s1->c != s2->c)
3829 return 0;
3830 while (s1 != NULL) {
3831 if (s2 == NULL)
3832 return 0;
3833 if (!is_compatible_types(s1->t, s2->t))
3834 return 0;
3835 s1 = s1->next;
3836 s2 = s2->next;
3838 if (s2)
3839 return 0;
3840 return 1;
3841 } else {
3842 /* XXX: not complete */
3843 return 1;
3847 /* print a type. If 'varstr' is not NULL, then the variable is also
3848 printed in the type */
3849 /* XXX: union */
3850 /* XXX: add array and function pointers */
3851 void type_to_str(char *buf, int buf_size,
3852 int t, const char *varstr)
3854 int bt, v;
3855 Sym *s, *sa;
3856 char buf1[256];
3857 const char *tstr;
3859 t = t & VT_TYPE;
3860 bt = t & VT_BTYPE;
3861 buf[0] = '\0';
3862 if (t & VT_UNSIGNED)
3863 pstrcat(buf, buf_size, "unsigned ");
3864 switch(bt) {
3865 case VT_VOID:
3866 tstr = "void";
3867 goto add_tstr;
3868 case VT_BOOL:
3869 tstr = "_Bool";
3870 goto add_tstr;
3871 case VT_BYTE:
3872 tstr = "char";
3873 goto add_tstr;
3874 case VT_SHORT:
3875 tstr = "short";
3876 goto add_tstr;
3877 case VT_INT:
3878 tstr = "int";
3879 goto add_tstr;
3880 case VT_LONG:
3881 tstr = "long";
3882 goto add_tstr;
3883 case VT_LLONG:
3884 tstr = "long long";
3885 goto add_tstr;
3886 case VT_FLOAT:
3887 tstr = "float";
3888 goto add_tstr;
3889 case VT_DOUBLE:
3890 tstr = "double";
3891 goto add_tstr;
3892 case VT_LDOUBLE:
3893 tstr = "long double";
3894 add_tstr:
3895 pstrcat(buf, buf_size, tstr);
3896 break;
3897 case VT_ENUM:
3898 case VT_STRUCT:
3899 if (bt == VT_STRUCT)
3900 tstr = "struct ";
3901 else
3902 tstr = "enum ";
3903 pstrcat(buf, buf_size, tstr);
3904 v = (unsigned)t >> VT_STRUCT_SHIFT;
3905 if (v >= SYM_FIRST_ANOM)
3906 pstrcat(buf, buf_size, "<anonymous>");
3907 else
3908 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3909 break;
3910 case VT_FUNC:
3911 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3912 type_to_str(buf, buf_size, s->t, varstr);
3913 pstrcat(buf, buf_size, "(");
3914 sa = s->next;
3915 while (sa != NULL) {
3916 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
3917 pstrcat(buf, buf_size, buf1);
3918 sa = sa->next;
3919 if (sa)
3920 pstrcat(buf, buf_size, ", ");
3922 pstrcat(buf, buf_size, ")");
3923 goto no_var;
3924 case VT_PTR:
3925 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3926 pstrcpy(buf1, sizeof(buf1), "*");
3927 if (varstr)
3928 pstrcat(buf1, sizeof(buf1), varstr);
3929 type_to_str(buf, buf_size, s->t, buf1);
3930 goto no_var;
3932 if (varstr) {
3933 pstrcat(buf, buf_size, " ");
3934 pstrcat(buf, buf_size, varstr);
3936 no_var: ;
3939 /* verify type compatibility to store vtop in 'dt' type, and generate
3940 casts if needed. */
3941 void gen_assign_cast(int dt)
3943 int st;
3944 char buf1[256], buf2[256];
3946 st = vtop->t; /* source type */
3947 if ((dt & VT_BTYPE) == VT_PTR) {
3948 /* special cases for pointers */
3949 /* a function is implicitely a function pointer */
3950 if ((st & VT_BTYPE) == VT_FUNC) {
3951 if (!is_compatible_types(pointed_type(dt), st))
3952 goto error;
3953 else
3954 goto type_ok;
3956 /* '0' can also be a pointer */
3957 if ((st & VT_BTYPE) == VT_INT &&
3958 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
3959 vtop->c.i == 0)
3960 goto type_ok;
3962 if (!is_compatible_types(dt, st)) {
3963 error:
3964 type_to_str(buf1, sizeof(buf1), st, NULL);
3965 type_to_str(buf2, sizeof(buf2), dt, NULL);
3966 error("cannot cast '%s' to '%s'", buf1, buf2);
3968 type_ok:
3969 gen_cast(dt);
3972 /* store vtop in lvalue pushed on stack */
3973 void vstore(void)
3975 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
3976 GFuncContext gf;
3978 ft = vtop[-1].t;
3979 sbt = vtop->t & VT_BTYPE;
3980 dbt = ft & VT_BTYPE;
3981 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
3982 (sbt == VT_INT && dbt == VT_SHORT)) {
3983 /* optimize char/short casts */
3984 delayed_cast = VT_MUSTCAST;
3985 vtop->t = ft & VT_TYPE;
3986 } else {
3987 delayed_cast = 0;
3988 gen_assign_cast(ft & VT_TYPE);
3991 if (sbt == VT_STRUCT) {
3992 /* if structure, only generate pointer */
3993 /* structure assignment : generate memcpy */
3994 /* XXX: optimize if small size */
3995 vdup();
3996 gfunc_start(&gf, FUNC_CDECL);
3997 /* type size */
3998 size = type_size(vtop->t, &align);
3999 vpushi(size);
4000 gfunc_param(&gf);
4001 /* source */
4002 vtop->t = VT_INT;
4003 gaddrof();
4004 gfunc_param(&gf);
4005 /* destination */
4006 vswap();
4007 vtop->t = VT_INT;
4008 gaddrof();
4009 gfunc_param(&gf);
4011 save_regs(0);
4012 vpushi((int)&memcpy);
4013 gfunc_call(&gf);
4014 /* leave source on stack */
4015 } else if (ft & VT_BITFIELD) {
4016 /* bitfield store handling */
4017 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4018 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4019 /* remove bit field info to avoid loops */
4020 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4022 /* duplicate destination */
4023 vdup();
4024 vtop[-1] = vtop[-2];
4026 /* mask and shift source */
4027 vpushi((1 << bit_size) - 1);
4028 gen_op('&');
4029 vpushi(bit_pos);
4030 gen_op(TOK_SHL);
4031 /* load destination, mask and or with source */
4032 vswap();
4033 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4034 gen_op('&');
4035 gen_op('|');
4036 /* store result */
4037 vstore();
4038 } else {
4039 #ifdef CONFIG_TCC_BCHECK
4040 /* bound check case */
4041 if (vtop[-1].r & VT_MUSTBOUND) {
4042 vswap();
4043 gbound();
4044 vswap();
4046 #endif
4047 rc = RC_INT;
4048 if (is_float(ft))
4049 rc = RC_FLOAT;
4050 r = gv(rc); /* generate value */
4051 /* if lvalue was saved on stack, must read it */
4052 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4053 SValue sv;
4054 t = get_reg(RC_INT);
4055 sv.t = VT_INT;
4056 sv.r = VT_LOCAL | VT_LVAL;
4057 sv.c.ul = vtop[-1].c.ul;
4058 load(t, &sv);
4059 vtop[-1].r = t | VT_LVAL;
4061 store(r, vtop - 1);
4062 /* two word case handling : store second register at word + 4 */
4063 if ((ft & VT_BTYPE) == VT_LLONG) {
4064 vswap();
4065 /* convert to int to increment easily */
4066 vtop->t = VT_INT;
4067 gaddrof();
4068 vpushi(4);
4069 gen_op('+');
4070 vtop->r |= VT_LVAL;
4071 vswap();
4072 /* XXX: it works because r2 is spilled last ! */
4073 store(vtop->r2, vtop - 1);
4075 vswap();
4076 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4077 vtop->r |= delayed_cast;
4081 /* post defines POST/PRE add. c is the token ++ or -- */
4082 void inc(int post, int c)
4084 test_lvalue();
4085 vdup(); /* save lvalue */
4086 if (post) {
4087 gv_dup(); /* duplicate value */
4088 vrotb(3);
4089 vrotb(3);
4091 /* add constant */
4092 vpushi(c - TOK_MID);
4093 gen_op('+');
4094 vstore(); /* store value */
4095 if (post)
4096 vpop(); /* if post op, return saved value */
4099 /* Parse GNUC __attribute__ extension. Currently, the following
4100 extensions are recognized:
4101 - aligned(n) : set data/function alignment.
4102 - section(x) : generate data/code in this section.
4103 - unused : currently ignored, but may be used someday.
4105 void parse_attribute(AttributeDef *ad)
4107 int t, n;
4109 next();
4110 skip('(');
4111 skip('(');
4112 while (tok != ')') {
4113 if (tok < TOK_IDENT)
4114 expect("attribute name");
4115 t = tok;
4116 next();
4117 switch(t) {
4118 case TOK_SECTION:
4119 case TOK___SECTION__:
4120 skip('(');
4121 if (tok != TOK_STR)
4122 expect("section name");
4123 ad->section = find_section(tokc.ts->str);
4124 next();
4125 skip(')');
4126 break;
4127 case TOK_ALIGNED:
4128 case TOK___ALIGNED__:
4129 skip('(');
4130 n = expr_const();
4131 if (n <= 0 || (n & (n - 1)) != 0)
4132 error("alignment must be a positive power of two");
4133 ad->aligned = n;
4134 skip(')');
4135 break;
4136 case TOK_UNUSED:
4137 case TOK___UNUSED__:
4138 /* currently, no need to handle it because tcc does not
4139 track unused objects */
4140 break;
4141 case TOK_NORETURN:
4142 case TOK___NORETURN__:
4143 /* currently, no need to handle it because tcc does not
4144 track unused objects */
4145 break;
4146 case TOK_CDECL:
4147 case TOK___CDECL:
4148 case TOK___CDECL__:
4149 ad->func_call = FUNC_CDECL;
4150 break;
4151 case TOK_STDCALL:
4152 case TOK___STDCALL:
4153 case TOK___STDCALL__:
4154 ad->func_call = FUNC_STDCALL;
4155 break;
4156 default:
4157 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4158 /* skip parameters */
4159 /* XXX: skip parenthesis too */
4160 if (tok == '(') {
4161 next();
4162 while (tok != ')' && tok != -1)
4163 next();
4164 next();
4166 break;
4168 if (tok != ',')
4169 break;
4170 next();
4172 skip(')');
4173 skip(')');
4176 /* enum/struct/union declaration */
4177 int struct_decl(int u)
4179 int a, t, b, v, size, align, maxalign, c, offset;
4180 int bit_size, bit_pos, bsize, bt, lbit_pos;
4181 Sym *s, *ss, **ps;
4182 AttributeDef ad;
4184 a = tok; /* save decl type */
4185 next();
4186 if (tok != '{') {
4187 v = tok;
4188 next();
4189 /* struct already defined ? return it */
4190 /* XXX: check consistency */
4191 s = sym_find(v | SYM_STRUCT);
4192 if (s) {
4193 if (s->t != a)
4194 error("invalid type");
4195 goto do_decl;
4197 } else {
4198 v = anon_sym++;
4200 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4201 /* put struct/union/enum name in type */
4202 do_decl:
4203 u = u | (v << VT_STRUCT_SHIFT);
4205 if (tok == '{') {
4206 next();
4207 if (s->c)
4208 error("struct/union/enum already defined");
4209 /* cannot be empty */
4210 c = 0;
4211 maxalign = 0;
4212 ps = &s->next;
4213 bit_pos = 0;
4214 offset = 0;
4215 while (1) {
4216 if (a == TOK_ENUM) {
4217 v = tok;
4218 next();
4219 if (tok == '=') {
4220 next();
4221 c = expr_const();
4223 /* enum symbols have static storage */
4224 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4225 if (tok == ',')
4226 next();
4227 c++;
4228 } else {
4229 parse_btype(&b, &ad);
4230 while (1) {
4231 bit_size = -1;
4232 v = 0;
4233 if (tok != ':') {
4234 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4235 if ((t & VT_BTYPE) == VT_FUNC ||
4236 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4237 error("invalid type for '%s'",
4238 get_tok_str(v, NULL));
4239 } else {
4240 t = b;
4242 if (tok == ':') {
4243 next();
4244 bit_size = expr_const();
4245 /* XXX: handle v = 0 case for messages */
4246 if (bit_size < 0)
4247 error("negative width in bit-field '%s'",
4248 get_tok_str(v, NULL));
4249 if (v && bit_size == 0)
4250 error("zero width for bit-field '%s'",
4251 get_tok_str(v, NULL));
4253 size = type_size(t, &align);
4254 lbit_pos = 0;
4255 if (bit_size >= 0) {
4256 bt = t & VT_BTYPE;
4257 if (bt != VT_INT &&
4258 bt != VT_BYTE &&
4259 bt != VT_SHORT)
4260 error("bitfields must have scalar type");
4261 bsize = size * 8;
4262 if (bit_size > bsize) {
4263 error("width of '%s' exceeds its type",
4264 get_tok_str(v, NULL));
4265 } else if (bit_size == bsize) {
4266 /* no need for bit fields */
4267 bit_pos = 0;
4268 } else if (bit_size == 0) {
4269 /* XXX: what to do if only padding in a
4270 structure ? */
4271 /* zero size: means to pad */
4272 if (bit_pos > 0)
4273 bit_pos = bsize;
4274 } else {
4275 /* we do not have enough room ? */
4276 if ((bit_pos + bit_size) > bsize)
4277 bit_pos = 0;
4278 lbit_pos = bit_pos;
4279 /* XXX: handle LSB first */
4280 t |= VT_BITFIELD |
4281 (bit_pos << VT_STRUCT_SHIFT) |
4282 (bit_size << (VT_STRUCT_SHIFT + 6));
4283 bit_pos += bit_size;
4285 } else {
4286 bit_pos = 0;
4288 if (v) {
4289 /* add new memory data only if starting
4290 bit field */
4291 if (lbit_pos == 0) {
4292 if (a == TOK_STRUCT) {
4293 c = (c + align - 1) & -align;
4294 offset = c;
4295 c += size;
4296 } else {
4297 offset = 0;
4298 if (size > c)
4299 c = size;
4301 if (align > maxalign)
4302 maxalign = align;
4304 #if 0
4305 printf("add field %s offset=%d",
4306 get_tok_str(v, NULL), offset);
4307 if (t & VT_BITFIELD) {
4308 printf(" pos=%d size=%d",
4309 (t >> VT_STRUCT_SHIFT) & 0x3f,
4310 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4312 printf("\n");
4313 #endif
4314 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4315 *ps = ss;
4316 ps = &ss->next;
4318 if (tok == ';' || tok == -1)
4319 break;
4320 skip(',');
4322 skip(';');
4324 if (tok == '}')
4325 break;
4327 skip('}');
4328 /* size for struct/union, dummy for enum */
4329 s->c = (c + maxalign - 1) & -maxalign;
4331 return u;
4334 /* return 0 if no type declaration. otherwise, return the basic type
4335 and skip it.
4337 int parse_btype(int *type_ptr, AttributeDef *ad)
4339 int t, u, type_found;
4340 Sym *s;
4342 memset(ad, 0, sizeof(AttributeDef));
4343 type_found = 0;
4344 t = 0;
4345 while(1) {
4346 switch(tok) {
4347 /* basic types */
4348 case TOK_CHAR:
4349 u = VT_BYTE;
4350 basic_type:
4351 next();
4352 basic_type1:
4353 if ((t & VT_BTYPE) != 0)
4354 error("too many basic types");
4355 t |= u;
4356 break;
4357 case TOK_VOID:
4358 u = VT_VOID;
4359 goto basic_type;
4360 case TOK_SHORT:
4361 u = VT_SHORT;
4362 goto basic_type;
4363 case TOK_INT:
4364 next();
4365 break;
4366 case TOK_LONG:
4367 next();
4368 if ((t & VT_BTYPE) == VT_DOUBLE) {
4369 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4370 } else if ((t & VT_BTYPE) == VT_LONG) {
4371 t = (t & ~VT_BTYPE) | VT_LLONG;
4372 } else {
4373 u = VT_LONG;
4374 goto basic_type1;
4376 break;
4377 case TOK_BOOL:
4378 u = VT_BOOL;
4379 goto basic_type;
4380 case TOK_FLOAT:
4381 u = VT_FLOAT;
4382 goto basic_type;
4383 case TOK_DOUBLE:
4384 next();
4385 if ((t & VT_BTYPE) == VT_LONG) {
4386 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4387 } else {
4388 u = VT_DOUBLE;
4389 goto basic_type1;
4391 break;
4392 case TOK_ENUM:
4393 u = struct_decl(VT_ENUM);
4394 goto basic_type1;
4395 case TOK_STRUCT:
4396 case TOK_UNION:
4397 u = struct_decl(VT_STRUCT);
4398 goto basic_type1;
4400 /* type modifiers */
4401 case TOK_CONST:
4402 case TOK_VOLATILE:
4403 case TOK_REGISTER:
4404 case TOK_SIGNED:
4405 case TOK___SIGNED__:
4406 case TOK_AUTO:
4407 case TOK_INLINE:
4408 case TOK___INLINE__:
4409 case TOK_RESTRICT:
4410 next();
4411 break;
4412 case TOK_UNSIGNED:
4413 t |= VT_UNSIGNED;
4414 next();
4415 break;
4417 /* storage */
4418 case TOK_EXTERN:
4419 t |= VT_EXTERN;
4420 next();
4421 break;
4422 case TOK_STATIC:
4423 t |= VT_STATIC;
4424 next();
4425 break;
4426 case TOK_TYPEDEF:
4427 t |= VT_TYPEDEF;
4428 next();
4429 break;
4430 /* GNUC attribute */
4431 case TOK___ATTRIBUTE__:
4432 parse_attribute(ad);
4433 break;
4434 default:
4435 s = sym_find(tok);
4436 if (!s || !(s->t & VT_TYPEDEF))
4437 goto the_end;
4438 t |= (s->t & ~VT_TYPEDEF);
4439 next();
4440 break;
4442 type_found = 1;
4444 the_end:
4445 /* long is never used as type */
4446 if ((t & VT_BTYPE) == VT_LONG)
4447 t = (t & ~VT_BTYPE) | VT_INT;
4448 *type_ptr = t;
4449 return type_found;
4452 int post_type(int t, AttributeDef *ad)
4454 int p, n, pt, l, t1;
4455 Sym **plast, *s, *first;
4456 AttributeDef ad1;
4458 if (tok == '(') {
4459 /* function declaration */
4460 next();
4461 l = 0;
4462 first = NULL;
4463 plast = &first;
4464 while (tok != ')') {
4465 /* read param name and compute offset */
4466 if (l != FUNC_OLD) {
4467 if (!parse_btype(&pt, &ad1)) {
4468 if (l) {
4469 error("invalid type");
4470 } else {
4471 l = FUNC_OLD;
4472 goto old_proto;
4475 l = FUNC_NEW;
4476 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4477 break;
4478 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4479 if ((pt & VT_BTYPE) == VT_VOID)
4480 error("parameter declared as void");
4481 } else {
4482 old_proto:
4483 n = tok;
4484 pt = VT_INT;
4485 next();
4487 /* array must be transformed to pointer according to ANSI C */
4488 pt &= ~VT_ARRAY;
4489 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4490 *plast = s;
4491 plast = &s->next;
4492 if (tok == ',') {
4493 next();
4494 if (l == FUNC_NEW && tok == TOK_DOTS) {
4495 l = FUNC_ELLIPSIS;
4496 next();
4497 break;
4501 /* if no parameters, then old type prototype */
4502 if (l == 0)
4503 l = FUNC_OLD;
4504 skip(')');
4505 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4506 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4507 /* we push a anonymous symbol which will contain the function prototype */
4508 p = anon_sym++;
4509 s = sym_push(p, t, ad->func_call, l);
4510 s->next = first;
4511 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4512 } else if (tok == '[') {
4513 /* array definition */
4514 next();
4515 n = -1;
4516 if (tok != ']') {
4517 n = expr_const();
4518 if (n < 0)
4519 error("invalid array size");
4521 skip(']');
4522 /* parse next post type */
4523 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4524 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4526 /* we push a anonymous symbol which will contain the array
4527 element type */
4528 p = anon_sym++;
4529 sym_push(p, t, 0, n);
4530 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4532 return t;
4535 /* Read a type declaration (except basic type), and return the
4536 type. 'td' is a bitmask indicating which kind of type decl is
4537 expected. 't' should contain the basic type. 'ad' is the attribute
4538 definition of the basic type. It can be modified by type_decl(). */
4539 int type_decl(AttributeDef *ad, int *v, int t, int td)
4541 int u, p;
4542 Sym *s;
4544 while (tok == '*') {
4545 next();
4546 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4547 next();
4548 t = mk_pointer(t);
4551 /* recursive type */
4552 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4553 if (tok == '(') {
4554 next();
4555 /* XXX: this is not correct to modify 'ad' at this point, but
4556 the syntax is not clear */
4557 if (tok == TOK___ATTRIBUTE__)
4558 parse_attribute(ad);
4559 u = type_decl(ad, v, 0, td);
4560 skip(')');
4561 } else {
4562 u = 0;
4563 /* type identifier */
4564 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4565 *v = tok;
4566 next();
4567 } else {
4568 if (!(td & TYPE_ABSTRACT))
4569 expect("identifier");
4570 *v = 0;
4573 /* append t at the end of u */
4574 t = post_type(t, ad);
4575 if (tok == TOK___ATTRIBUTE__)
4576 parse_attribute(ad);
4577 if (!u)
4578 return t;
4579 p = u;
4580 while(1) {
4581 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4582 p = s->t;
4583 if (!p) {
4584 s->t = t;
4585 break;
4588 return u;
4591 /* define a new external reference to a symbol 'v' of type 'u' */
4592 Sym *external_sym(int v, int u, int r)
4594 Sym *s;
4596 s = sym_find(v);
4597 if (!s) {
4598 /* push forward reference */
4599 s = sym_push1(&global_stack,
4600 v, u | VT_EXTERN, 0);
4601 s->r = r | VT_CONST | VT_SYM;
4603 return s;
4606 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4607 static int lvalue_type(int t)
4609 int bt, r;
4610 r = VT_LVAL;
4611 bt = t & VT_BTYPE;
4612 if (bt == VT_BYTE)
4613 r |= VT_LVAL_BYTE;
4614 else if (bt == VT_SHORT)
4615 r |= VT_LVAL_SHORT;
4616 else
4617 return r;
4618 if (t & VT_UNSIGNED)
4619 r |= VT_LVAL_UNSIGNED;
4620 return r;
4623 /* indirection with full error checking and bound check */
4624 static void indir(void)
4626 if ((vtop->t & VT_BTYPE) != VT_PTR)
4627 expect("pointer");
4628 if (vtop->r & VT_LVAL)
4629 gv(RC_INT);
4630 vtop->t = pointed_type(vtop->t);
4631 /* an array is never an lvalue */
4632 if (!(vtop->t & VT_ARRAY)) {
4633 vtop->r |= lvalue_type(vtop->t);
4634 /* if bound checking, the referenced pointer must be checked */
4635 if (do_bounds_check)
4636 vtop->r |= VT_MUSTBOUND;
4640 /* pass a parameter to a function and do type checking and casting */
4641 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
4643 int func_type;
4644 func_type = func->c;
4645 if (func_type == FUNC_OLD ||
4646 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
4647 /* default casting : only need to convert float to double */
4648 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
4649 gen_cast(VT_DOUBLE);
4650 } else if (arg == NULL) {
4651 error("too many arguments to function");
4652 } else {
4653 gen_assign_cast(arg->t);
4655 gfunc_param(gf);
4658 void unary(void)
4660 int n, t, ft, fc, p, align, size, r, data_offset;
4661 Sym *s;
4662 GFuncContext gf;
4663 AttributeDef ad;
4665 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
4666 vpushi(tokc.i);
4667 next();
4668 } else if (tok == TOK_CUINT) {
4669 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
4670 next();
4671 } else if (tok == TOK_CLLONG) {
4672 vsetc(VT_LLONG, VT_CONST, &tokc);
4673 next();
4674 } else if (tok == TOK_CULLONG) {
4675 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
4676 next();
4677 } else if (tok == TOK_CFLOAT) {
4678 vsetc(VT_FLOAT, VT_CONST, &tokc);
4679 next();
4680 } else if (tok == TOK_CDOUBLE) {
4681 vsetc(VT_DOUBLE, VT_CONST, &tokc);
4682 next();
4683 } else if (tok == TOK_CLDOUBLE) {
4684 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
4685 next();
4686 } else if (tok == TOK___FUNC__) {
4687 /* special function name identifier */
4688 /* generate (char *) type */
4689 data_offset = data_section->data_ptr - data_section->data;
4690 vpush_ref(mk_pointer(VT_BYTE), data_section, data_offset);
4691 strcpy(data_section->data + data_offset, funcname);
4692 data_offset += strlen(funcname) + 1;
4693 data_section->data_ptr = data_section->data + data_offset;
4694 next();
4695 } else if (tok == TOK_LSTR) {
4696 t = VT_INT;
4697 goto str_init;
4698 } else if (tok == TOK_STR) {
4699 /* string parsing */
4700 t = VT_BYTE;
4701 str_init:
4702 type_size(t, &align);
4703 data_offset = data_section->data_ptr - data_section->data;
4704 data_offset = (data_offset + align - 1) & -align;
4705 fc = data_offset;
4706 /* we must declare it as an array first to use initializer parser */
4707 t = VT_ARRAY | mk_pointer(t);
4708 decl_initializer(t, data_section, data_offset, 1, 0);
4709 data_offset += type_size(t, &align);
4710 /* put it as pointer */
4711 vpush_ref(t & ~VT_ARRAY, data_section, fc);
4712 data_section->data_ptr = data_section->data + data_offset;
4713 } else {
4714 t = tok;
4715 next();
4716 if (t == '(') {
4717 /* cast ? */
4718 if (parse_btype(&t, &ad)) {
4719 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4720 skip(')');
4721 /* check ISOC99 compound literal */
4722 if (tok == '{') {
4723 /* data is allocated locally by default */
4724 if (global_expr)
4725 r = VT_CONST;
4726 else
4727 r = VT_LOCAL;
4728 /* all except arrays are lvalues */
4729 if (!(ft & VT_ARRAY))
4730 r |= lvalue_type(ft);
4731 memset(&ad, 0, sizeof(AttributeDef));
4732 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
4733 } else {
4734 unary();
4735 gen_cast(ft);
4737 } else {
4738 gexpr();
4739 skip(')');
4741 } else if (t == '*') {
4742 unary();
4743 indir();
4744 } else if (t == '&') {
4745 unary();
4746 /* functions names must be treated as function pointers,
4747 except for unary '&' and sizeof. Since we consider that
4748 functions are not lvalues, we only have to handle it
4749 there and in function calls. */
4750 /* arrays can also be used although they are not lvalues */
4751 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
4752 !(vtop->t & VT_ARRAY))
4753 test_lvalue();
4754 vtop->t = mk_pointer(vtop->t);
4755 gaddrof();
4756 } else
4757 if (t == '!') {
4758 unary();
4759 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
4760 vtop->c.i = !vtop->c.i;
4761 else if ((vtop->r & VT_VALMASK) == VT_CMP)
4762 vtop->c.i = vtop->c.i ^ 1;
4763 else
4764 vset(VT_INT, VT_JMP, gtst(1, 0));
4765 } else
4766 if (t == '~') {
4767 unary();
4768 vpushi(-1);
4769 gen_op('^');
4770 } else
4771 if (t == '+') {
4772 unary();
4773 } else
4774 if (t == TOK_SIZEOF) {
4775 if (tok == '(') {
4776 next();
4777 if (parse_btype(&t, &ad)) {
4778 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4779 } else {
4780 /* XXX: some code could be generated: add eval
4781 flag */
4782 gexpr();
4783 t = vtop->t;
4784 vpop();
4786 skip(')');
4787 } else {
4788 unary();
4789 t = vtop->t;
4790 vpop();
4792 vpushi(type_size(t, &t));
4793 } else
4794 if (t == TOK_INC || t == TOK_DEC) {
4795 unary();
4796 inc(0, t);
4797 } else if (t == '-') {
4798 vpushi(0);
4799 unary();
4800 gen_op('-');
4801 } else
4803 if (t < TOK_UIDENT)
4804 expect("identifier");
4805 s = sym_find(t);
4806 if (!s) {
4807 if (tok != '(')
4808 error("'%s' undeclared", get_tok_str(t, NULL));
4809 /* for simple function calls, we tolerate undeclared
4810 external reference */
4811 p = anon_sym++;
4812 sym_push1(&global_stack, p, 0, FUNC_OLD);
4813 /* int() function */
4814 s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT), 0);
4816 vset(s->t, s->r, s->c);
4817 /* if forward reference, we must point to s */
4818 if (vtop->r & VT_SYM)
4819 vtop->c.sym = s;
4823 /* post operations */
4824 while (1) {
4825 if (tok == TOK_INC || tok == TOK_DEC) {
4826 inc(1, tok);
4827 next();
4828 } else if (tok == '.' || tok == TOK_ARROW) {
4829 /* field */
4830 if (tok == TOK_ARROW)
4831 indir();
4832 test_lvalue();
4833 gaddrof();
4834 next();
4835 /* expect pointer on structure */
4836 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
4837 expect("struct or union");
4838 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4839 /* find field */
4840 tok |= SYM_FIELD;
4841 while ((s = s->next) != NULL) {
4842 if (s->v == tok)
4843 break;
4845 if (!s)
4846 error("field not found");
4847 /* add field offset to pointer */
4848 vtop->t = char_pointer_type; /* change type to 'char *' */
4849 vpushi(s->c);
4850 gen_op('+');
4851 /* change type to field type, and set to lvalue */
4852 vtop->t = s->t;
4853 /* an array is never an lvalue */
4854 if (!(vtop->t & VT_ARRAY))
4855 vtop->r |= lvalue_type(vtop->t);
4856 next();
4857 } else if (tok == '[') {
4858 next();
4859 gexpr();
4860 gen_op('+');
4861 indir();
4862 skip(']');
4863 } else if (tok == '(') {
4864 SValue ret;
4865 Sym *sa;
4867 /* function call */
4868 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
4869 /* pointer test (no array accepted) */
4870 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4871 vtop->t = pointed_type(vtop->t);
4872 if ((vtop->t & VT_BTYPE) != VT_FUNC)
4873 goto error_func;
4874 } else {
4875 error_func:
4876 expect("function pointer");
4878 } else {
4879 vtop->r &= ~VT_LVAL; /* no lvalue */
4881 /* get return type */
4882 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
4883 save_regs(0); /* save used temporary registers */
4884 gfunc_start(&gf, s->r);
4885 next();
4886 sa = s->next; /* first parameter */
4887 #ifdef INVERT_FUNC_PARAMS
4889 int parlevel;
4890 Sym *args, *s1;
4891 ParseState saved_parse_state;
4892 TokenString str;
4894 /* read each argument and store it on a stack */
4895 /* XXX: merge it with macro args ? */
4896 args = NULL;
4897 if (tok != ')') {
4898 for(;;) {
4899 tok_str_new(&str);
4900 parlevel = 0;
4901 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
4902 tok != -1) {
4903 if (tok == '(')
4904 parlevel++;
4905 else if (tok == ')')
4906 parlevel--;
4907 tok_str_add_tok(&str);
4908 next();
4910 tok_str_add(&str, -1); /* end of file added */
4911 tok_str_add(&str, 0);
4912 s1 = sym_push2(&args, 0, 0, (int)str.str);
4913 s1->next = sa; /* add reference to argument */
4914 if (sa)
4915 sa = sa->next;
4916 if (tok == ')')
4917 break;
4918 skip(',');
4922 /* now generate code in reverse order by reading the stack */
4923 save_parse_state(&saved_parse_state);
4924 while (args) {
4925 macro_ptr = (int *)args->c;
4926 next();
4927 expr_eq();
4928 if (tok != -1)
4929 expect("',' or ')'");
4930 gfunc_param_typed(&gf, s, args->next);
4931 s1 = args->prev;
4932 free((int *)args->c);
4933 free(args);
4934 args = s1;
4936 restore_parse_state(&saved_parse_state);
4938 #endif
4939 /* compute first implicit argument if a structure is returned */
4940 if ((s->t & VT_BTYPE) == VT_STRUCT) {
4941 /* get some space for the returned structure */
4942 size = type_size(s->t, &align);
4943 loc = (loc - size) & -align;
4944 ret.t = s->t;
4945 ret.r = VT_LOCAL | VT_LVAL;
4946 /* pass it as 'int' to avoid structure arg passing
4947 problems */
4948 vset(VT_INT, VT_LOCAL, loc);
4949 ret.c = vtop->c;
4950 gfunc_param(&gf);
4951 } else {
4952 ret.t = s->t;
4953 ret.r2 = VT_CONST;
4954 /* return in register */
4955 if (is_float(ret.t)) {
4956 ret.r = REG_FRET;
4957 } else {
4958 if ((ret.t & VT_BTYPE) == VT_LLONG)
4959 ret.r2 = REG_LRET;
4960 ret.r = REG_IRET;
4962 ret.c.i = 0;
4964 #ifndef INVERT_FUNC_PARAMS
4965 if (tok != ')') {
4966 for(;;) {
4967 expr_eq();
4968 gfunc_param_typed(&gf, s, sa);
4969 if (sa)
4970 sa = sa->next;
4971 if (tok == ')')
4972 break;
4973 skip(',');
4976 #endif
4977 if (sa)
4978 error("too few arguments to function");
4979 skip(')');
4980 gfunc_call(&gf);
4981 /* return value */
4982 vsetc(ret.t, ret.r, &ret.c);
4983 vtop->r2 = ret.r2;
4984 } else {
4985 break;
4990 void uneq(void)
4992 int t;
4994 unary();
4995 if (tok == '=' ||
4996 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4997 tok == TOK_A_XOR || tok == TOK_A_OR ||
4998 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4999 test_lvalue();
5000 t = tok;
5001 next();
5002 if (t == '=') {
5003 expr_eq();
5004 } else {
5005 vdup();
5006 expr_eq();
5007 gen_op(t & 0x7f);
5009 vstore();
5013 void sum(int l)
5015 int t;
5017 if (l == 0)
5018 uneq();
5019 else {
5020 sum(--l);
5021 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5022 (l == 1 && (tok == '+' || tok == '-')) ||
5023 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5024 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5025 tok == TOK_ULT || tok == TOK_UGE)) ||
5026 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5027 (l == 5 && tok == '&') ||
5028 (l == 6 && tok == '^') ||
5029 (l == 7 && tok == '|') ||
5030 (l == 8 && tok == TOK_LAND) ||
5031 (l == 9 && tok == TOK_LOR)) {
5032 t = tok;
5033 next();
5034 sum(l);
5035 gen_op(t);
5040 /* only used if non constant */
5041 void eand(void)
5043 int t;
5045 sum(8);
5046 t = 0;
5047 while (1) {
5048 if (tok != TOK_LAND) {
5049 if (t) {
5050 t = gtst(1, t);
5051 vset(VT_INT, VT_JMPI, t);
5053 break;
5055 t = gtst(1, t);
5056 next();
5057 sum(8);
5061 void eor(void)
5063 int t;
5065 eand();
5066 t = 0;
5067 while (1) {
5068 if (tok != TOK_LOR) {
5069 if (t) {
5070 t = gtst(0, t);
5071 vset(VT_INT, VT_JMP, t);
5073 break;
5075 t = gtst(0, t);
5076 next();
5077 eand();
5081 /* XXX: better constant handling */
5082 void expr_eq(void)
5084 int t, u, c, r1, r2, rc;
5086 if (const_wanted) {
5087 sum(10);
5088 if (tok == '?') {
5089 c = vtop->c.i;
5090 vpop();
5091 next();
5092 gexpr();
5093 t = vtop->c.i;
5094 vpop();
5095 skip(':');
5096 expr_eq();
5097 if (c)
5098 vtop->c.i = t;
5100 } else {
5101 eor();
5102 if (tok == '?') {
5103 next();
5104 save_regs(1); /* we need to save all registers here except
5105 at the top because it is a branch point */
5106 t = gtst(1, 0);
5107 gexpr();
5108 /* XXX: long long handling ? */
5109 rc = RC_INT;
5110 if (is_float(vtop->t))
5111 rc = RC_FLOAT;
5112 r1 = gv(rc);
5113 vtop--; /* no vpop so that FP stack is not flushed */
5114 skip(':');
5115 u = gjmp(0);
5117 gsym(t);
5118 expr_eq();
5119 r2 = gv(rc);
5120 move_reg(r1, r2);
5121 vtop->r = r1;
5122 gsym(u);
5127 void gexpr(void)
5129 while (1) {
5130 expr_eq();
5131 if (tok != ',')
5132 break;
5133 vpop();
5134 next();
5138 /* parse a constant expression and return value in vtop */
5139 void expr_const1(void)
5141 int a;
5142 a = const_wanted;
5143 const_wanted = 1;
5144 expr_eq();
5145 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5146 expect("constant");
5147 const_wanted = a;
5150 /* parse an integer constant and return its value */
5151 int expr_const(void)
5153 int c;
5154 expr_const1();
5155 c = vtop->c.i;
5156 vpop();
5157 return c;
5160 /* return the label token if current token is a label, otherwise
5161 return zero */
5162 int is_label(void)
5164 int t;
5165 CValue c;
5167 /* fast test first */
5168 if (tok < TOK_UIDENT)
5169 return 0;
5170 /* no need to save tokc since we expect an identifier */
5171 t = tok;
5172 c = tokc;
5173 next();
5174 if (tok == ':') {
5175 next();
5176 return t;
5177 } else {
5178 /* XXX: may not work in all cases (macros ?) */
5179 tok1 = tok;
5180 tok1c = tokc;
5181 tok = t;
5182 tokc = c;
5183 return 0;
5187 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5189 int a, b, c, d;
5190 Sym *s;
5192 /* generate line number info */
5193 if (do_debug &&
5194 (last_line_num != file->line_num || last_ind != ind)) {
5195 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5196 last_ind = ind;
5197 last_line_num = file->line_num;
5200 if (tok == TOK_IF) {
5201 /* if test */
5202 next();
5203 skip('(');
5204 gexpr();
5205 skip(')');
5206 a = gtst(1, 0);
5207 block(bsym, csym, case_sym, def_sym, case_reg);
5208 c = tok;
5209 if (c == TOK_ELSE) {
5210 next();
5211 d = gjmp(0);
5212 gsym(a);
5213 block(bsym, csym, case_sym, def_sym, case_reg);
5214 gsym(d); /* patch else jmp */
5215 } else
5216 gsym(a);
5217 } else if (tok == TOK_WHILE) {
5218 next();
5219 d = ind;
5220 skip('(');
5221 gexpr();
5222 skip(')');
5223 a = gtst(1, 0);
5224 b = 0;
5225 block(&a, &b, case_sym, def_sym, case_reg);
5226 gjmp_addr(d);
5227 gsym(a);
5228 gsym_addr(b, d);
5229 } else if (tok == '{') {
5230 next();
5231 /* declarations */
5232 s = local_stack.top;
5233 while (tok != '}') {
5234 decl(VT_LOCAL);
5235 if (tok != '}')
5236 block(bsym, csym, case_sym, def_sym, case_reg);
5238 /* pop locally defined symbols */
5239 sym_pop(&local_stack, s);
5240 next();
5241 } else if (tok == TOK_RETURN) {
5242 next();
5243 if (tok != ';') {
5244 gexpr();
5245 gen_assign_cast(func_vt);
5246 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5247 /* if returning structure, must copy it to implicit
5248 first pointer arg location */
5249 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5250 indir();
5251 vswap();
5252 /* copy structure value to pointer */
5253 vstore();
5254 } else if (is_float(func_vt)) {
5255 gv(RC_FRET);
5256 } else {
5257 gv(RC_IRET);
5259 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5261 skip(';');
5262 rsym = gjmp(rsym); /* jmp */
5263 } else if (tok == TOK_BREAK) {
5264 /* compute jump */
5265 if (!bsym)
5266 error("cannot break");
5267 *bsym = gjmp(*bsym);
5268 next();
5269 skip(';');
5270 } else if (tok == TOK_CONTINUE) {
5271 /* compute jump */
5272 if (!csym)
5273 error("cannot continue");
5274 *csym = gjmp(*csym);
5275 next();
5276 skip(';');
5277 } else if (tok == TOK_FOR) {
5278 int e;
5279 next();
5280 skip('(');
5281 if (tok != ';') {
5282 gexpr();
5283 vpop();
5285 skip(';');
5286 d = ind;
5287 c = ind;
5288 a = 0;
5289 b = 0;
5290 if (tok != ';') {
5291 gexpr();
5292 a = gtst(1, 0);
5294 skip(';');
5295 if (tok != ')') {
5296 e = gjmp(0);
5297 c = ind;
5298 gexpr();
5299 vpop();
5300 gjmp_addr(d);
5301 gsym(e);
5303 skip(')');
5304 block(&a, &b, case_sym, def_sym, case_reg);
5305 gjmp_addr(c);
5306 gsym(a);
5307 gsym_addr(b, c);
5308 } else
5309 if (tok == TOK_DO) {
5310 next();
5311 a = 0;
5312 b = 0;
5313 d = ind;
5314 block(&a, &b, case_sym, def_sym, case_reg);
5315 skip(TOK_WHILE);
5316 skip('(');
5317 gsym(b);
5318 gexpr();
5319 c = gtst(0, 0);
5320 gsym_addr(c, d);
5321 skip(')');
5322 gsym(a);
5323 skip(';');
5324 } else
5325 if (tok == TOK_SWITCH) {
5326 next();
5327 skip('(');
5328 gexpr();
5329 /* XXX: other types than integer */
5330 case_reg = gv(RC_INT);
5331 vpop();
5332 skip(')');
5333 a = 0;
5334 b = gjmp(0); /* jump to first case */
5335 c = 0;
5336 block(&a, csym, &b, &c, case_reg);
5337 /* if no default, jmp after switch */
5338 if (c == 0)
5339 c = ind;
5340 /* default label */
5341 gsym_addr(b, c);
5342 /* break label */
5343 gsym(a);
5344 } else
5345 if (tok == TOK_CASE) {
5346 int v1, v2;
5347 if (!case_sym)
5348 expect("switch");
5349 next();
5350 v1 = expr_const();
5351 v2 = v1;
5352 if (gnu_ext && tok == TOK_DOTS) {
5353 next();
5354 v2 = expr_const();
5355 if (v2 < v1)
5356 warning("empty case range");
5358 /* since a case is like a label, we must skip it with a jmp */
5359 b = gjmp(0);
5360 gsym(*case_sym);
5361 vset(VT_INT, case_reg, 0);
5362 vpushi(v1);
5363 if (v1 == v2) {
5364 gen_op(TOK_EQ);
5365 *case_sym = gtst(1, 0);
5366 } else {
5367 gen_op(TOK_GE);
5368 *case_sym = gtst(1, 0);
5369 vset(VT_INT, case_reg, 0);
5370 vpushi(v2);
5371 gen_op(TOK_LE);
5372 *case_sym = gtst(1, *case_sym);
5374 gsym(b);
5375 skip(':');
5376 block(bsym, csym, case_sym, def_sym, case_reg);
5377 } else
5378 if (tok == TOK_DEFAULT) {
5379 next();
5380 skip(':');
5381 if (!def_sym)
5382 expect("switch");
5383 if (*def_sym)
5384 error("too many 'default'");
5385 *def_sym = ind;
5386 block(bsym, csym, case_sym, def_sym, case_reg);
5387 } else
5388 if (tok == TOK_GOTO) {
5389 next();
5390 s = sym_find1(&label_stack, tok);
5391 /* put forward definition if needed */
5392 if (!s)
5393 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5394 /* label already defined */
5395 if (s->t & LABEL_FORWARD)
5396 s->c = gjmp(s->c);
5397 else
5398 gjmp_addr(s->c);
5399 next();
5400 skip(';');
5401 } else {
5402 b = is_label();
5403 if (b) {
5404 /* label case */
5405 s = sym_find1(&label_stack, b);
5406 if (s) {
5407 if (!(s->t & LABEL_FORWARD))
5408 error("multiple defined label");
5409 gsym(s->c);
5410 s->c = ind;
5411 s->t = 0;
5412 } else {
5413 sym_push1(&label_stack, b, 0, ind);
5415 /* we accept this, but it is a mistake */
5416 if (tok == '}')
5417 warning("deprecated use of label at end of compound statement");
5418 else
5419 block(bsym, csym, case_sym, def_sym, case_reg);
5420 } else {
5421 /* expression case */
5422 if (tok != ';') {
5423 gexpr();
5424 vpop();
5426 skip(';');
5431 /* t is the array or struct type. c is the array or struct
5432 address. cur_index/cur_field is the pointer to the current
5433 value. 'size_only' is true if only size info is needed (only used
5434 in arrays) */
5435 void decl_designator(int t, Section *sec, unsigned long c,
5436 int *cur_index, Sym **cur_field,
5437 int size_only)
5439 Sym *s, *f;
5440 int notfirst, index, align, l;
5442 notfirst = 0;
5443 if (gnu_ext && (l = is_label()) != 0)
5444 goto struct_field;
5446 while (tok == '[' || tok == '.') {
5447 if (tok == '[') {
5448 if (!(t & VT_ARRAY))
5449 expect("array type");
5450 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5451 next();
5452 index = expr_const();
5453 if (index < 0 || (s->c >= 0 && index >= s->c))
5454 expect("invalid index");
5455 skip(']');
5456 if (!notfirst)
5457 *cur_index = index;
5458 t = pointed_type(t);
5459 c += index * type_size(t, &align);
5460 } else {
5461 next();
5462 l = tok;
5463 next();
5464 struct_field:
5465 if ((t & VT_BTYPE) != VT_STRUCT)
5466 expect("struct/union type");
5467 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5468 l |= SYM_FIELD;
5469 f = s->next;
5470 while (f) {
5471 if (f->v == l)
5472 break;
5473 f = f->next;
5475 if (!f)
5476 expect("field");
5477 if (!notfirst)
5478 *cur_field = f;
5479 t = f->t | (t & ~VT_TYPE);
5480 c += f->c;
5482 notfirst = 1;
5484 if (notfirst) {
5485 if (tok == '=') {
5486 next();
5487 } else {
5488 if (!gnu_ext)
5489 expect("=");
5491 } else {
5492 if (t & VT_ARRAY) {
5493 index = *cur_index;
5494 t = pointed_type(t);
5495 c += index * type_size(t, &align);
5496 } else {
5497 f = *cur_field;
5498 if (!f)
5499 error("too many field init");
5500 t = f->t | (t & ~VT_TYPE);
5501 c += f->c;
5504 decl_initializer(t, sec, c, 0, size_only);
5507 #define EXPR_VAL 0
5508 #define EXPR_CONST 1
5509 #define EXPR_ANY 2
5511 /* store a value or an expression directly in global data or in local array */
5512 void init_putv(int t, Section *sec, unsigned long c,
5513 int v, int expr_type)
5515 int saved_global_expr, bt;
5516 void *ptr;
5518 switch(expr_type) {
5519 case EXPR_VAL:
5520 vpushi(v);
5521 break;
5522 case EXPR_CONST:
5523 /* compound literals must be allocated globally in this case */
5524 saved_global_expr = global_expr;
5525 global_expr = 1;
5526 expr_const1();
5527 global_expr = saved_global_expr;
5528 break;
5529 case EXPR_ANY:
5530 expr_eq();
5531 break;
5534 if (sec) {
5535 /* XXX: not portable */
5536 /* XXX: generate error if incorrect relocation */
5537 gen_assign_cast(t);
5538 bt = t & VT_BTYPE;
5539 ptr = sec->data + c;
5540 if ((vtop->r & VT_SYM) &&
5541 (bt == VT_BYTE ||
5542 bt == VT_SHORT ||
5543 bt == VT_DOUBLE ||
5544 bt == VT_LDOUBLE ||
5545 bt == VT_LLONG))
5546 error("initializer element is not computable at load time");
5547 switch(bt) {
5548 case VT_BYTE:
5549 *(char *)ptr = vtop->c.i;
5550 break;
5551 case VT_SHORT:
5552 *(short *)ptr = vtop->c.i;
5553 break;
5554 case VT_DOUBLE:
5555 *(double *)ptr = vtop->c.d;
5556 break;
5557 case VT_LDOUBLE:
5558 *(long double *)ptr = vtop->c.ld;
5559 break;
5560 case VT_LLONG:
5561 *(long long *)ptr = vtop->c.ll;
5562 break;
5563 default:
5564 if (vtop->r & VT_SYM) {
5565 greloc(sec, vtop->c.sym, c, R_DATA_32);
5566 *(int *)ptr = 0;
5567 } else {
5568 *(int *)ptr = vtop->c.i;
5570 break;
5572 vtop--;
5573 } else {
5574 vset(t, VT_LOCAL, c);
5575 vswap();
5576 vstore();
5577 vpop();
5581 /* put zeros for variable based init */
5582 void init_putz(int t, Section *sec, unsigned long c, int size)
5584 GFuncContext gf;
5586 if (sec) {
5587 /* nothing to do because globals are already set to zero */
5588 } else {
5589 gfunc_start(&gf, FUNC_CDECL);
5590 vpushi(size);
5591 gfunc_param(&gf);
5592 vpushi(0);
5593 gfunc_param(&gf);
5594 vset(VT_INT, VT_LOCAL, c);
5595 gfunc_param(&gf);
5596 vpushi((int)&memset);
5597 gfunc_call(&gf);
5601 /* 't' contains the type and storage info. 'c' is the offset of the
5602 object in section 'sec'. If 'sec' is NULL, it means stack based
5603 allocation. 'first' is true if array '{' must be read (multi
5604 dimension implicit array init handling). 'size_only' is true if
5605 size only evaluation is wanted (only for arrays). */
5606 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only)
5608 int index, array_length, n, no_oblock, nb, parlevel, i;
5609 int t1, size1, align1, expr_type;
5610 Sym *s, *f;
5611 TokenSym *ts;
5613 if (t & VT_ARRAY) {
5614 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5615 n = s->c;
5616 array_length = 0;
5617 t1 = pointed_type(t);
5618 size1 = type_size(t1, &align1);
5620 no_oblock = 1;
5621 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5622 tok == '{') {
5623 skip('{');
5624 no_oblock = 0;
5627 /* only parse strings here if correct type (otherwise: handle
5628 them as ((w)char *) expressions */
5629 if ((tok == TOK_LSTR &&
5630 (t1 & VT_BTYPE) == VT_INT) ||
5631 (tok == TOK_STR &&
5632 (t1 & VT_BTYPE) == VT_BYTE)) {
5633 /* XXX: move multiple string parsing in parser ? */
5634 while (tok == TOK_STR || tok == TOK_LSTR) {
5635 ts = tokc.ts;
5636 /* compute maximum number of chars wanted */
5637 nb = ts->len;
5638 if (n >= 0 && nb > (n - array_length))
5639 nb = n - array_length;
5640 if (!size_only) {
5641 if (ts->len > nb)
5642 warning("initializer-string for array is too long");
5643 for(i=0;i<nb;i++) {
5644 init_putv(t1, sec, c + (array_length + i) * size1,
5645 ts->str[i], EXPR_VAL);
5648 array_length += nb;
5649 next();
5651 /* only add trailing zero if enough storage (no
5652 warning in this case since it is standard) */
5653 if (n < 0 || array_length < n) {
5654 if (!size_only) {
5655 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5657 array_length++;
5659 } else {
5660 index = 0;
5661 while (tok != '}') {
5662 decl_designator(t, sec, c, &index, NULL, size_only);
5663 if (n >= 0 && index >= n)
5664 error("index too large");
5665 /* must put zero in holes (note that doing it that way
5666 ensures that it even works with designators) */
5667 if (!size_only && array_length < index) {
5668 init_putz(t1, sec, c + array_length * size1,
5669 (index - array_length) * size1);
5671 index++;
5672 if (index > array_length)
5673 array_length = index;
5674 /* special test for multi dimensional arrays (may not
5675 be strictly correct if designators are used at the
5676 same time) */
5677 if (index >= n && no_oblock)
5678 break;
5679 if (tok == '}')
5680 break;
5681 skip(',');
5684 if (!no_oblock)
5685 skip('}');
5686 /* put zeros at the end */
5687 if (!size_only && n >= 0 && array_length < n) {
5688 init_putz(t1, sec, c + array_length * size1,
5689 (n - array_length) * size1);
5691 /* patch type size if needed */
5692 if (n < 0)
5693 s->c = array_length;
5694 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
5695 /* XXX: union needs only one init */
5696 next();
5697 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5698 f = s->next;
5699 array_length = 0;
5700 index = 0;
5701 n = s->c;
5702 while (tok != '}') {
5703 decl_designator(t, sec, c, NULL, &f, size_only);
5704 /* fill with zero between fields */
5705 index = f->c;
5706 if (!size_only && array_length < index) {
5707 init_putz(t, sec, c + array_length,
5708 index - array_length);
5710 index = index + type_size(f->t, &align1);
5711 if (index > array_length)
5712 array_length = index;
5713 if (tok == '}')
5714 break;
5715 skip(',');
5716 f = f->next;
5718 /* put zeros at the end */
5719 if (!size_only && array_length < n) {
5720 init_putz(t, sec, c + array_length,
5721 n - array_length);
5723 skip('}');
5724 } else if (tok == '{') {
5725 next();
5726 decl_initializer(t, sec, c, first, size_only);
5727 skip('}');
5728 } else if (size_only) {
5729 /* just skip expression */
5730 parlevel = 0;
5731 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
5732 tok != -1) {
5733 if (tok == '(')
5734 parlevel++;
5735 else if (tok == ')')
5736 parlevel--;
5737 next();
5739 } else {
5740 /* currently, we always use constant expression for globals
5741 (may change for scripting case) */
5742 expr_type = EXPR_CONST;
5743 if (!sec)
5744 expr_type = EXPR_ANY;
5745 init_putv(t, sec, c, 0, expr_type);
5749 /* parse an initializer for type 't' if 'has_init' is true, and
5750 allocate space in local or global data space ('r' is either
5751 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5752 variable 'v' of scope 'scope' is declared before initializers are
5753 parsed. If 'v' is zero, then a reference to the new object is put
5754 in the value stack. */
5755 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
5756 int v, int scope)
5758 int size, align, addr, data_offset;
5759 int level;
5760 ParseState saved_parse_state;
5761 TokenString init_str;
5762 Section *sec;
5764 size = type_size(t, &align);
5765 /* If unknown size, we must evaluate it before
5766 evaluating initializers because
5767 initializers can generate global data too
5768 (e.g. string pointers or ISOC99 compound
5769 literals). It also simplifies local
5770 initializers handling */
5771 tok_str_new(&init_str);
5772 if (size < 0) {
5773 if (!has_init)
5774 error("unknown type size");
5775 /* get all init string */
5776 level = 0;
5777 while (level > 0 || (tok != ',' && tok != ';')) {
5778 if (tok < 0)
5779 error("unexpected end of file in initializer");
5780 tok_str_add_tok(&init_str);
5781 if (tok == '{')
5782 level++;
5783 else if (tok == '}') {
5784 if (level == 0)
5785 break;
5786 level--;
5788 next();
5790 tok_str_add(&init_str, -1);
5791 tok_str_add(&init_str, 0);
5793 /* compute size */
5794 save_parse_state(&saved_parse_state);
5796 macro_ptr = init_str.str;
5797 next();
5798 decl_initializer(t, NULL, 0, 1, 1);
5799 /* prepare second initializer parsing */
5800 macro_ptr = init_str.str;
5801 next();
5803 /* if still unknown size, error */
5804 size = type_size(t, &align);
5805 if (size < 0)
5806 error("unknown type size");
5808 /* take into account specified alignment if bigger */
5809 if (ad->aligned > align)
5810 align = ad->aligned;
5811 if ((r & VT_VALMASK) == VT_LOCAL) {
5812 sec = NULL;
5813 if (do_bounds_check && (t & VT_ARRAY))
5814 loc--;
5815 #ifdef TCC_TARGET_IL
5816 /* XXX: ugly patch to allocate local variables for IL, just
5817 for testing */
5818 addr = loc;
5819 loc++;
5820 #else
5821 loc = (loc - size) & -align;
5822 addr = loc;
5823 #endif
5824 /* handles bounds */
5825 /* XXX: currently, since we do only one pass, we cannot track
5826 '&' operators, so we add only arrays */
5827 if (do_bounds_check && (t & VT_ARRAY)) {
5828 int *bounds_ptr;
5829 /* add padding between regions */
5830 loc--;
5831 /* then add local bound info */
5832 bounds_ptr = (int *)lbounds_section->data_ptr;
5833 *bounds_ptr++ = addr;
5834 *bounds_ptr++ = size;
5835 lbounds_section->data_ptr = (unsigned char *)bounds_ptr;
5837 } else {
5838 /* compute section */
5839 sec = ad->section;
5840 if (!sec) {
5841 if (has_init)
5842 sec = data_section;
5843 else
5844 sec = bss_section;
5846 data_offset = sec->data_ptr - sec->data;
5847 data_offset = (data_offset + align - 1) & -align;
5848 addr = data_offset;
5849 /* very important to increment global pointer at this time
5850 because initializers themselves can create new initializers */
5851 data_offset += size;
5852 /* handles bounds */
5853 if (do_bounds_check) {
5854 int *bounds_ptr;
5855 /* first, we need to add at least one byte between each region */
5856 data_offset++;
5857 /* then add global bound info */
5858 bounds_ptr = (int *)bounds_section->data_ptr;
5859 /* XXX: add relocation */
5860 *bounds_ptr++ = addr + (unsigned long)sec->data;
5861 *bounds_ptr++ = size;
5862 bounds_section->data_ptr = (unsigned char *)bounds_ptr;
5864 sec->data_ptr = sec->data + data_offset;
5866 if (v) {
5867 Sym *sym;
5869 if (!sec) {
5870 /* local variable */
5871 sym_push(v, t, r, addr);
5872 } else {
5873 if (scope == VT_CONST) {
5874 /* global scope: see if already defined */
5875 sym = sym_find(v);
5876 if (!sym)
5877 goto do_def;
5878 if (!is_compatible_types(sym->t, t))
5879 error("incompatible types for redefinition of '%s'",
5880 get_tok_str(v, NULL));
5881 if (!(sym->t & VT_EXTERN))
5882 error("redefinition of '%s'", get_tok_str(v, NULL));
5883 sym->t &= ~VT_EXTERN;
5884 } else {
5885 do_def:
5886 sym = sym_push(v, t, r | VT_SYM, 0);
5888 put_extern_sym(sym, sec, addr);
5890 } else {
5891 if (!sec) {
5892 /* push local reference */
5893 vset(t, r, addr);
5894 } else {
5895 /* push global reference */
5896 vpush_ref(t, sec, addr);
5899 if (has_init) {
5900 decl_initializer(t, sec, addr, 1, 0);
5901 /* restore parse state if needed */
5902 if (init_str.str) {
5903 free(init_str.str);
5904 restore_parse_state(&saved_parse_state);
5909 void put_func_debug(int t)
5911 char buf[512];
5913 /* stabs info */
5914 /* XXX: we put here a dummy type */
5915 snprintf(buf, sizeof(buf), "%s:%c1",
5916 funcname, t & VT_STATIC ? 'f' : 'F');
5917 put_stabs(buf, N_FUN, 0, file->line_num, ind);
5918 func_ind = ind;
5919 last_ind = 0;
5920 last_line_num = 0;
5923 /* not finished : try to put some local vars in registers */
5924 //#define CONFIG_REG_VARS
5926 #ifdef CONFIG_REG_VARS
5927 void add_var_ref(int t)
5929 printf("%s:%d: &%s\n",
5930 file->filename, file->line_num,
5931 get_tok_str(t, NULL));
5934 /* first pass on a function with heuristic to extract variable usage
5935 and pointer references to local variables for register allocation */
5936 void analyse_function(void)
5938 int level, t;
5940 for(;;) {
5941 if (tok == -1)
5942 break;
5943 /* any symbol coming after '&' is considered as being a
5944 variable whose reference is taken. It is highly unaccurate
5945 but it is difficult to do better without a complete parse */
5946 if (tok == '&') {
5947 next();
5948 /* if '& number', then no need to examine next tokens */
5949 if (tok == TOK_CINT ||
5950 tok == TOK_CUINT ||
5951 tok == TOK_CLLONG ||
5952 tok == TOK_CULLONG) {
5953 continue;
5954 } else if (tok >= TOK_UIDENT) {
5955 /* if '& ident [' or '& ident ->', then ident address
5956 is not needed */
5957 t = tok;
5958 next();
5959 if (tok != '[' && tok != TOK_ARROW)
5960 add_var_ref(t);
5961 } else {
5962 level = 0;
5963 while (tok != '}' && tok != ';' &&
5964 !((tok == ',' || tok == ')') && level == 0)) {
5965 if (tok >= TOK_UIDENT) {
5966 add_var_ref(tok);
5967 } else if (tok == '(') {
5968 level++;
5969 } else if (tok == ')') {
5970 level--;
5972 next();
5975 } else {
5976 next();
5980 #endif
5982 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5983 void decl(int l)
5985 int t, b, v, has_init, r;
5986 Sym *sym;
5987 AttributeDef ad;
5989 while (1) {
5990 if (!parse_btype(&b, &ad)) {
5991 /* skip redundant ';' */
5992 /* XXX: find more elegant solution */
5993 if (tok == ';') {
5994 next();
5995 continue;
5997 /* special test for old K&R protos without explicit int
5998 type. Only accepted when defining global data */
5999 if (l == VT_LOCAL || tok < TOK_DEFINE)
6000 break;
6001 b = VT_INT;
6003 if (((b & VT_BTYPE) == VT_ENUM ||
6004 (b & VT_BTYPE) == VT_STRUCT) &&
6005 tok == ';') {
6006 /* we accept no variable after */
6007 next();
6008 continue;
6010 while (1) { /* iterate thru each declaration */
6011 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6012 #if 0
6014 char buf[500];
6015 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6016 printf("type = '%s'\n", buf);
6018 #endif
6019 if (tok == '{') {
6020 #ifdef CONFIG_REG_VARS
6021 TokenString func_str;
6022 ParseState saved_parse_state;
6023 int block_level;
6024 #endif
6026 if (l == VT_LOCAL)
6027 error("cannot use local functions");
6028 if (!(t & VT_FUNC))
6029 expect("function definition");
6031 #ifdef CONFIG_REG_VARS
6032 /* parse all function code and record it */
6034 tok_str_new(&func_str);
6036 block_level = 0;
6037 for(;;) {
6038 int t;
6039 if (tok == -1)
6040 error("unexpected end of file");
6041 tok_str_add_tok(&func_str);
6042 t = tok;
6043 next();
6044 if (t == '{') {
6045 block_level++;
6046 } else if (t == '}') {
6047 block_level--;
6048 if (block_level == 0)
6049 break;
6052 tok_str_add(&func_str, -1);
6053 tok_str_add(&func_str, 0);
6055 save_parse_state(&saved_parse_state);
6057 macro_ptr = func_str.str;
6058 next();
6059 analyse_function();
6060 #endif
6062 /* compute text section */
6063 cur_text_section = ad.section;
6064 if (!cur_text_section)
6065 cur_text_section = text_section;
6066 ind = (int)cur_text_section->data_ptr;
6067 funcname = get_tok_str(v, NULL);
6068 sym = sym_find(v);
6069 if (sym) {
6070 /* if symbol is already defined, then put complete type */
6071 sym->t = t;
6072 } else {
6073 /* put function symbol */
6074 sym = sym_push1(&global_stack, v, t, 0);
6076 put_extern_sym(sym, cur_text_section,
6077 ind - (int)cur_text_section->data);
6078 sym->r = VT_SYM | VT_CONST;
6079 /* put debug symbol */
6080 if (do_debug)
6081 put_func_debug(t);
6082 /* push a dummy symbol to enable local sym storage */
6083 sym_push1(&local_stack, 0, 0, 0);
6084 gfunc_prolog(t);
6085 loc = 0;
6086 rsym = 0;
6087 #ifdef CONFIG_REG_VARS
6088 macro_ptr = func_str.str;
6089 next();
6090 #endif
6091 block(NULL, NULL, NULL, NULL, 0);
6092 gsym(rsym);
6093 gfunc_epilog();
6094 cur_text_section->data_ptr = (unsigned char *)ind;
6095 sym_pop(&label_stack, NULL); /* reset label stack */
6096 sym_pop(&local_stack, NULL); /* reset local stack */
6097 /* end of function */
6098 if (do_debug) {
6099 put_stabn(N_FUN, 0, 0, ind - func_ind);
6101 funcname = ""; /* for safety */
6102 func_vt = VT_VOID; /* for safety */
6103 ind = 0; /* for safety */
6105 #ifdef CONFIG_REG_VARS
6106 free(func_str.str);
6107 restore_parse_state(&saved_parse_state);
6108 #endif
6109 break;
6110 } else {
6111 if (b & VT_TYPEDEF) {
6112 /* save typedefed type */
6113 /* XXX: test storage specifiers ? */
6114 sym_push(v, t | VT_TYPEDEF, 0, 0);
6115 } else if ((t & VT_BTYPE) == VT_FUNC) {
6116 /* external function definition */
6117 external_sym(v, t, 0);
6118 } else {
6119 /* not lvalue if array */
6120 r = 0;
6121 if (!(t & VT_ARRAY))
6122 r |= lvalue_type(t);
6123 if (b & VT_EXTERN) {
6124 /* external variable */
6125 external_sym(v, t, r);
6126 } else {
6127 if (t & VT_STATIC)
6128 r |= VT_CONST;
6129 else
6130 r |= l;
6131 has_init = (tok == '=');
6132 if (has_init)
6133 next();
6134 decl_initializer_alloc(t, &ad, r,
6135 has_init, v, l);
6138 if (tok != ',') {
6139 skip(';');
6140 break;
6142 next();
6148 /* compile the C file opened in 'file'. Return non zero if errors. */
6149 int tcc_compile(TCCState *s)
6151 Sym *define_start;
6152 char buf[512];
6154 funcname = "";
6155 include_stack_ptr = include_stack;
6156 ifdef_stack_ptr = ifdef_stack;
6158 vtop = vstack - 1;
6159 anon_sym = SYM_FIRST_ANOM;
6161 /* file info: full path + filename */
6162 if (do_debug) {
6163 getcwd(buf, sizeof(buf));
6164 pstrcat(buf, sizeof(buf), "/");
6165 put_stabs(buf, N_SO, 0, 0, (unsigned long)text_section->data_ptr);
6166 put_stabs(file->filename, N_SO, 0, 0,
6167 (unsigned long)text_section->data_ptr);
6169 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6170 symbols can be safely used */
6171 put_elf_sym(symtab_section, 0, 0,
6172 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6173 SHN_ABS, file->filename);
6175 /* define common 'char *' type because it is often used internally
6176 for arrays and struct dereference */
6177 char_pointer_type = mk_pointer(VT_BYTE);
6179 define_start = define_stack.top;
6180 inp();
6181 ch = '\n'; /* needed to parse correctly first preprocessor command */
6182 next();
6183 decl(VT_CONST);
6184 if (tok != -1)
6185 expect("declaration");
6187 /* end of translation unit info */
6188 if (do_debug) {
6189 put_stabn(N_SO, 0, 0, (unsigned long)text_section->data_ptr);
6192 /* reset define stack, but leave -Dsymbols (may be incorrect if
6193 they are undefined) */
6194 sym_pop(&define_stack, define_start);
6196 sym_pop(&global_stack, NULL);
6198 return 0;
6201 int tcc_compile_file(TCCState *s, const char *filename1)
6203 int ret;
6204 file = tcc_open(filename1);
6205 if (!file)
6206 error("file '%s' not found", filename1);
6207 ret = tcc_compile(s);
6208 tcc_close(file);
6209 return ret;
6212 int tcc_compile_string(TCCState *s, const char *str)
6214 BufferedFile bf1, *bf = &bf1;
6215 int ret;
6217 /* init file structure */
6218 bf->fd = -1;
6219 bf->buf_ptr = (char *)str;
6220 bf->buf_end = (char *)str + strlen(bf->buffer);
6221 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6222 bf->line_num = 1;
6223 file = bf;
6225 ret = tcc_compile(s);
6227 /* currently, no need to close */
6228 return ret;
6231 /* define a symbol. A value can also be provided with the '=' operator */
6232 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6234 BufferedFile bf1, *bf = &bf1;
6236 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6237 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6238 /* default value */
6239 if (!value)
6240 value = "1";
6241 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6243 /* init file structure */
6244 bf->fd = -1;
6245 bf->buf_ptr = bf->buffer;
6246 bf->buf_end = bf->buffer + strlen(bf->buffer);
6247 bf->filename[0] = '\0';
6248 bf->line_num = 1;
6249 file = bf;
6251 include_stack_ptr = include_stack;
6253 /* parse with define parser */
6254 inp();
6255 ch = '\n'; /* needed to parse correctly first preprocessor command */
6256 next_nomacro();
6257 parse_define();
6258 file = NULL;
6261 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6263 TokenSym *ts;
6264 Sym *s;
6265 ts = tok_alloc(sym, 0);
6266 s = sym_find1(&define_stack, tok);
6267 /* undefine symbol by putting an invalid name */
6268 if (s)
6269 sym_undef(&define_stack, s);
6272 /* open a dynamic library so that its symbol are available for
6273 compiled programs */
6274 /* XXX: open the lib only to actually run the program */
6275 int tcc_add_dll(TCCState *s, const char *library_name)
6277 void *h;
6279 h = dlopen(library_name, RTLD_GLOBAL | RTLD_LAZY);
6280 if (!h)
6281 error((char *)dlerror());
6282 return 0;
6285 static int put_elf_str(Section *s, const char *sym)
6287 int c, offset;
6288 offset = s->data_ptr - s->data;
6289 for(;;) {
6290 c = *sym++;
6291 *s->data_ptr++ = c;
6292 if (c == '\0')
6293 break;
6295 return offset;
6298 /* elf symbol hashing function */
6299 static unsigned long elf_hash(const unsigned char *name)
6301 unsigned long h = 0, g;
6303 while (*name) {
6304 h = (h << 4) + *name++;
6305 g = h & 0xf0000000;
6306 if (g)
6307 h ^= g >> 24;
6308 h &= ~g;
6310 return h;
6313 /* return the symbol number */
6314 static int put_elf_sym(Section *s,
6315 unsigned long value, unsigned long size,
6316 int info, int other, int shndx, const char *name)
6318 int name_offset, nbuckets, h, sym_index;
6319 Elf32_Sym *sym;
6320 Section *hs;
6322 sym = (Elf32_Sym *)s->data_ptr;
6323 if (name)
6324 name_offset = put_elf_str(s->link, name);
6325 else
6326 name_offset = 0;
6327 /* XXX: endianness */
6328 sym->st_name = name_offset;
6329 sym->st_value = value;
6330 sym->st_size = size;
6331 sym->st_info = info;
6332 sym->st_other = other;
6333 sym->st_shndx = shndx;
6334 sym_index = sym - (Elf32_Sym *)s->data;
6335 hs = s->hash;
6336 if (hs && ELF32_ST_BIND(info) == STB_GLOBAL) {
6337 /* add another hashing entry */
6338 nbuckets = ((int *)hs->data)[0];
6339 ((int *)hs->data)[1]++;
6340 h = elf_hash(name) % nbuckets;
6341 ((int *)hs->data)[2 + nbuckets + sym_index] = ((int *)hs->data)[2 + h];
6342 ((int *)hs->data)[2 + h] = sym_index;
6344 s->data_ptr += sizeof(Elf32_Sym);
6345 return sym_index;
6348 /* find global ELF symbol 'name' and return its index. Return 0 if not
6349 found. */
6350 static int find_elf_sym(Section *s, const char *name)
6352 Elf32_Sym *sym;
6353 Section *hs;
6354 int nbuckets, sym_index, h;
6355 const char *name1;
6357 hs = s->hash;
6358 if (!hs)
6359 return 0;
6360 nbuckets = ((int *)hs->data)[0];
6361 h = elf_hash(name) % nbuckets;
6362 sym_index = ((int *)hs->data)[2 + h];
6363 while (sym_index != 0) {
6364 sym = &((Elf32_Sym *)s->data)[sym_index];
6365 name1 = s->link->data + sym->st_name;
6366 if (!strcmp(name, name1))
6367 return sym_index;
6368 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
6370 return 0;
6373 /* update sym->c so that it points to an external symbol in section
6374 'section' with value 'value' */
6375 /* XXX: get rid of put_elf_sym */
6376 void put_extern_sym(Sym *sym, Section *section, unsigned long value)
6378 int sym_type, sym_bind, sh_num;
6379 Elf32_Sym *esym;
6380 const char *name;
6382 if (section)
6383 sh_num = section->sh_num;
6384 else
6385 sh_num = SHN_UNDEF;
6386 if (!sym->c) {
6387 if ((sym->t & VT_BTYPE) == VT_FUNC)
6388 sym_type = STT_FUNC;
6389 else
6390 sym_type = STT_OBJECT;
6391 if (sym->t & VT_STATIC)
6392 sym_bind = STB_LOCAL;
6393 else
6394 sym_bind = STB_GLOBAL;
6395 /* if the symbol is global, then we look if it is already
6396 defined */
6397 name = get_tok_str(sym->v, NULL);
6398 if (sym_bind == STB_GLOBAL) {
6399 sym->c = find_elf_sym(symtab_section, name);
6400 if (!sym->c)
6401 goto do_def;
6402 /* check if not defined */
6403 if (section) {
6404 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6405 if (esym->st_shndx != SHN_UNDEF)
6406 error("'%s' defined twice", name);
6407 esym->st_shndx = sh_num;
6408 esym->st_value = value;
6410 } else {
6411 do_def:
6412 sym->c = put_elf_sym(symtab_section, value, 0,
6413 ELF32_ST_INFO(sym_bind, sym_type), 0,
6414 sh_num, name);
6416 } else {
6417 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6418 esym->st_value = value;
6419 esym->st_shndx = sh_num;
6423 /* put relocation */
6424 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
6425 int type, int symbol)
6427 char buf[256];
6428 Section *sr;
6429 Elf32_Rel *rel;
6431 sr = s->reloc;
6432 if (!sr) {
6433 /* if no relocation section, create it */
6434 snprintf(buf, sizeof(buf), ".rel%s", s->name);
6435 sr = new_section(buf, SHT_REL, s->sh_flags);
6436 sr->sh_entsize = sizeof(Elf32_Rel);
6437 sr->link = symtab;
6438 sr->sh_info = s->sh_num;
6439 s->reloc = sr;
6441 rel = (Elf32_Rel *)sr->data_ptr;
6442 /* XXX: endianness */
6443 rel->r_offset = offset;
6444 rel->r_info = ELF32_R_INFO(symbol, type);
6445 sr->data_ptr += sizeof(Elf32_Rel);
6448 /* put stab debug information */
6450 typedef struct {
6451 unsigned long n_strx; /* index into string table of name */
6452 unsigned char n_type; /* type of symbol */
6453 unsigned char n_other; /* misc info (usually empty) */
6454 unsigned short n_desc; /* description field */
6455 unsigned long n_value; /* value of symbol */
6456 } Stab_Sym;
6458 static void put_stabs(const char *str, int type, int other, int desc, int value)
6460 Stab_Sym *sym;
6462 sym = (Stab_Sym *)stab_section->data_ptr;
6463 if (str) {
6464 sym->n_strx = put_elf_str(stabstr_section, str);
6465 } else {
6466 sym->n_strx = 0;
6468 sym->n_type = type;
6469 sym->n_other = other;
6470 sym->n_desc = desc;
6471 sym->n_value = value;
6473 stab_section->data_ptr += sizeof(Stab_Sym);
6476 static void put_stabn(int type, int other, int desc, int value)
6478 put_stabs(NULL, type, other, desc, value);
6481 static void put_stabd(int type, int other, int desc)
6483 put_stabs(NULL, type, other, desc, 0);
6486 /* In an ELF file symbol table, the local symbols must appear below
6487 the global and weak ones. Since TCC cannot sort it while generating
6488 the code, we must do it after. All the relocation tables are also
6489 modified to take into account the symbol table sorting */
6490 static void sort_symbols(Section *s)
6492 int *old_to_new_syms;
6493 Elf32_Sym *new_syms;
6494 int nb_syms, i;
6495 Elf32_Sym *p, *q;
6496 Elf32_Rel *rel;
6497 Section *sr;
6498 int type, sym_index;
6500 nb_syms = (s->data_ptr - s->data) / sizeof(Elf32_Sym);
6501 new_syms = malloc(nb_syms * sizeof(Elf32_Sym));
6502 if (!new_syms)
6503 error("memory full");
6504 old_to_new_syms = malloc(nb_syms * sizeof(int));
6505 if (!old_to_new_syms)
6506 error("memory full");
6507 /* first pass for local symbols */
6508 p = (Elf32_Sym *)s->data;
6509 q = new_syms;
6510 for(i = 0; i < nb_syms; i++) {
6511 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
6512 old_to_new_syms[i] = q - new_syms;
6513 *q++ = *p;
6515 p++;
6517 /* save the number of local symbols in section header */
6518 s->sh_info = q - new_syms;
6520 /* then second pass for non local symbols */
6521 p = (Elf32_Sym *)s->data;
6522 for(i = 0; i < nb_syms; i++) {
6523 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
6524 old_to_new_syms[i] = q - new_syms;
6525 *q++ = *p;
6527 p++;
6530 /* we copy the new symbols to the old */
6531 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
6532 free(new_syms);
6534 /* now we modify all the relocations */
6535 for(sr = first_section; sr != NULL; sr = sr->next) {
6536 if (sr->sh_type == SHT_REL && sr->link == s) {
6537 for(rel = (Elf32_Rel *)sr->data;
6538 rel < (Elf32_Rel *)sr->data_ptr;
6539 rel++) {
6540 sym_index = ELF32_R_SYM(rel->r_info);
6541 type = ELF32_R_TYPE(rel->r_info);
6542 sym_index = old_to_new_syms[sym_index];
6543 rel->r_info = ELF32_R_INFO(sym_index, type);
6548 free(old_to_new_syms);
6551 static Section *new_section_hash(const char *name, int sh_flags,
6552 int nb_buckets, Section *symtab)
6554 Section *hash;
6555 hash = new_section(name, SHT_HASH, sh_flags);
6556 ((int *)hash->data)[0] = nb_buckets;
6557 ((int *)hash->data)[1] = 1;
6558 hash->sh_entsize = sizeof(int);
6559 hash->data_ptr += (2 + nb_buckets + 1) * sizeof(int);
6560 symtab->hash = hash;
6561 hash->link = symtab;
6562 return hash;
6565 /* put dynamic tag */
6566 static void put_dt(Section *dynamic, int dt, unsigned long val)
6568 Elf32_Dyn *dyn;
6569 dyn = (Elf32_Dyn *)dynamic->data_ptr;
6570 dyn->d_tag = dt;
6571 dyn->d_un.d_val = val;
6572 dynamic->data_ptr += sizeof(Elf32_Dyn);
6575 /* add dynamic sections so that the executable is dynamically linked */
6576 static char elf_interp[] = "/lib/ld-linux.so.2";
6578 #define ELF_START_ADDR 0x08048000
6579 #define ELF_PAGE_SIZE 0x1000
6581 /* XXX: suppress that */
6582 static void put32(unsigned char *p, unsigned int val)
6584 p[0] = val;
6585 p[1] = val >> 8;
6586 p[2] = val >> 16;
6587 p[3] = val >> 24;
6590 /* output an ELF file (currently, only for testing) */
6591 /* XXX: generate startup code */
6592 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6593 int tcc_output_file(TCCState *s1, const char *filename, int file_type)
6595 Elf32_Ehdr ehdr;
6596 FILE *f;
6597 int fd, mode;
6598 int *section_order;
6599 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index;
6600 unsigned long addr;
6601 Section *strsec, *s;
6602 Elf32_Shdr shdr, *sh;
6603 Elf32_Phdr *phdr, *ph;
6604 Section *interp, *plt, *got, *dynamic, *dynsym, *dynstr, *hash;
6605 unsigned char *saved_dynamic_data_ptr;
6606 Elf32_Sym *sym;
6607 int type;
6609 interp = NULL;
6610 dynamic = NULL;
6611 plt = NULL; /* avoid warning */
6612 got = NULL; /* avoid warning */
6613 dynsym = NULL; /* avoid warning */
6614 hash = NULL; /* avoid warning */
6615 dynstr = NULL; /* avoid warning */
6616 saved_dynamic_data_ptr = NULL; /* avoid warning */
6618 if (file_type != TCC_FILE_OBJ && !static_link) {
6619 const char *name;
6620 int nb_plt_entries;
6622 if (file_type == TCC_FILE_EXE) {
6623 /* add interpreter section only if executable */
6624 interp = new_section(".interp", SHT_PROGBITS, SHF_ALLOC);
6625 interp->sh_addralign = 1;
6626 strcpy(interp->data_ptr, elf_interp);
6627 interp->data_ptr += sizeof(elf_interp);
6630 /* add dynamic symbol table */
6631 dynsym = new_section(".dynsym", SHT_DYNSYM, SHF_ALLOC);
6632 dynsym->sh_entsize = sizeof(Elf32_Sym);
6633 dynstr = new_section(".dynstr", SHT_STRTAB, SHF_ALLOC);
6634 put_elf_str(dynstr, "");
6635 dynsym->link = dynstr;
6636 put_elf_sym(dynsym, 0, 0, 0, 0, 0, NULL);
6638 /* hash table */
6639 hash = new_section_hash(".hash", SHF_ALLOC,
6640 ELF_DYNSYM_HASH_SIZE, dynsym);
6642 /* add dynamic section */
6643 dynamic = new_section(".dynamic", SHT_DYNAMIC,
6644 SHF_ALLOC | SHF_WRITE);
6645 dynamic->link = dynstr;
6646 dynamic->sh_entsize = sizeof(Elf32_Dyn);
6648 /* add PLT and GOT */
6649 plt = new_section(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
6650 plt->sh_entsize = 4;
6651 got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6652 got->sh_entsize = 4;
6654 /* add undefined symbols in dynamic symbol table */
6655 nb_plt_entries = 0;
6656 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6657 sym < (Elf32_Sym *)symtab_section->data_ptr;
6658 sym++) {
6659 if (sym->st_shndx == SHN_UNDEF) {
6660 name = symtab_section->link->data + sym->st_name;
6661 type = ELF32_ST_TYPE(sym->st_info);
6662 put_elf_sym(dynsym, 0, 0,
6663 sym->st_info, 0, SHN_UNDEF, name);
6664 if (type == STT_FUNC) {
6665 nb_plt_entries++;
6666 /* prepare space for relocation */
6667 put_elf_reloc(dynsym, got, 0, 0, 0);
6672 /* update PLT/GOT sizes so that we can allocate their space */
6673 plt->data_ptr += 16 * (nb_plt_entries + 1);
6674 got->data_ptr += 4 * (nb_plt_entries + 3);
6676 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, "libc.so.6"));
6677 /* XXX: add other libs */
6679 /* add necessary space for other entries */
6680 saved_dynamic_data_ptr = dynamic->data_ptr;
6681 dynamic->data_ptr += 8 * 9;
6684 sort_symbols(symtab_section);
6686 memset(&ehdr, 0, sizeof(ehdr));
6688 /* we add a section for symbols */
6689 strsec = new_section(".shstrtab", SHT_STRTAB, 0);
6690 put_elf_str(strsec, "");
6692 /* compute number of sections */
6693 shnum = nb_sections;
6695 /* this array is used to reorder sections in the output file */
6696 section_order = malloc(sizeof(int) * shnum);
6697 if (!section_order)
6698 error("memory full");
6699 section_order[0] = 0;
6700 sh_order_index = 1;
6702 /* compute number of program headers */
6703 switch(file_type) {
6704 default:
6705 case TCC_FILE_OBJ:
6706 phnum = 0;
6707 break;
6708 case TCC_FILE_EXE:
6709 if (!static_link)
6710 phnum = 4;
6711 else
6712 phnum = 2;
6713 break;
6714 case TCC_FILE_DLL:
6715 phnum = 3;
6716 break;
6719 /* allocate strings for section names */
6720 for(i = 1; i < nb_sections; i++) {
6721 s = sections[i];
6722 s->sh_name = put_elf_str(strsec, s->name);
6723 s->sh_size = s->data_ptr - s->data;
6726 /* allocate program segment headers */
6727 phdr = malloc(phnum * sizeof(Elf32_Phdr));
6728 if (!phdr)
6729 error("memory full");
6730 memset(phdr, 0, phnum * sizeof(Elf32_Phdr));
6732 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
6733 if (phnum > 0) {
6734 /* compute section to program header mapping */
6735 if (file_type == TCC_FILE_DLL)
6736 addr = 0;
6737 else
6738 addr = ELF_START_ADDR;
6740 /* compute address after headers */
6741 addr += (file_offset & (ELF_PAGE_SIZE - 1));
6743 /* leave one program header for the program interpreter */
6744 ph = &phdr[0];
6745 if (interp)
6746 ph++;
6748 for(j = 0; j < 2; j++) {
6749 ph->p_type = PT_LOAD;
6750 if (j == 0)
6751 ph->p_flags = PF_R | PF_X;
6752 else
6753 ph->p_flags = PF_R | PF_W;
6754 ph->p_align = ELF_PAGE_SIZE;
6756 for(i = 1; i < nb_sections; i++) {
6757 s = sections[i];
6758 /* compute if section should be included */
6759 if (j == 0) {
6760 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
6761 SHF_ALLOC)
6762 continue;
6763 } else {
6764 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
6765 (SHF_ALLOC | SHF_WRITE))
6766 continue;
6768 section_order[sh_order_index++] = i;
6770 /* section matches: we align it and add its size */
6771 tmp = file_offset;
6772 file_offset = (file_offset + s->sh_addralign - 1) &
6773 ~(s->sh_addralign - 1);
6774 s->sh_offset = file_offset;
6775 addr += file_offset - tmp;
6776 s->sh_addr = addr;
6778 if (ph->p_offset == 0) {
6779 ph->p_offset = file_offset;
6780 ph->p_vaddr = addr;
6781 ph->p_paddr = ph->p_vaddr;
6783 addr += s->sh_size;
6784 file_offset += s->sh_size;
6786 ph->p_filesz = file_offset - ph->p_offset;
6787 ph->p_memsz = addr - ph->p_vaddr;
6788 ph++;
6791 /* if interpreter, then add corresponing program header */
6792 if (interp) {
6793 ph = &phdr[0];
6795 ph->p_type = PT_INTERP;
6796 ph->p_offset = interp->sh_offset;
6797 ph->p_vaddr = interp->sh_addr;
6798 ph->p_paddr = ph->p_vaddr;
6799 ph->p_filesz = interp->sh_size;
6800 ph->p_memsz = interp->sh_size;
6801 ph->p_flags = PF_R;
6802 ph->p_align = interp->sh_addralign;
6805 /* if dynamic section, then add corresponing program header */
6806 if (dynamic) {
6807 int sym_index, plt_offset;
6808 unsigned char *p;
6810 ph = &phdr[phnum - 1];
6812 ph->p_type = PT_DYNAMIC;
6813 ph->p_offset = dynamic->sh_offset;
6814 ph->p_vaddr = dynamic->sh_addr;
6815 ph->p_paddr = ph->p_vaddr;
6816 ph->p_filesz = dynamic->sh_size;
6817 ph->p_memsz = dynamic->sh_size;
6818 ph->p_flags = PF_R | PF_W;
6819 ph->p_align = dynamic->sh_addralign;
6821 /* now all the sections are mapped, so we can compute all
6822 PLT/GOT stuff */
6824 /* first three got entries */
6825 got->data_ptr = got->data;
6826 plt->data_ptr = plt->data;
6827 if (got->reloc)
6828 got->reloc->data_ptr = got->reloc->data;
6830 put32(got->data_ptr, dynamic->sh_addr);
6831 got->data_ptr += 4;
6832 put32(got->data_ptr, 0);
6833 got->data_ptr += 4;
6834 put32(got->data_ptr, 0);
6835 got->data_ptr += 4;
6837 /* first plt entry */
6838 p = plt->data_ptr;
6839 p[0] = 0xff; /* pushl got + 4 */
6840 p[1] = 0x35;
6841 put32(p + 2, got->sh_addr + 4);
6842 p[6] = 0xff; /* jmp *(got + 8) */
6843 p[7] = 0x25;
6844 put32(p + 8, got->sh_addr + 8);
6845 plt->data_ptr += 16;
6847 /* add undefined symbols in dynamic symbol table. also update
6848 PLT and GOT if needed */
6849 plt_offset = 0;
6850 sym_index = 1;
6851 for(sym = (Elf32_Sym *)dynsym->data + 1;
6852 sym < (Elf32_Sym *)dynsym->data_ptr;
6853 sym++) {
6854 type = ELF32_ST_TYPE(sym->st_info);
6855 if (type == STT_FUNC) {
6856 /* one more entry in PLT */
6857 p = plt->data_ptr;
6858 p[0] = 0xff; /* jmp *(got + x) */
6859 p[1] = 0x25;
6860 put32(p + 2, got->sh_addr + got->data_ptr - got->data);
6861 p[6] = 0x68; /* push $xxx */
6862 put32(p + 7, plt_offset);
6863 p[11] = 0xe9; /* jmp plt_start */
6864 put32(p + 12, -(plt->data_ptr + 16 - plt->data));
6866 /* patch symbol value to point to plt */
6867 sym->st_value = plt->sh_addr + p - plt->data;
6869 plt_offset += 8;
6870 plt->data_ptr += 16;
6872 /* corresponding got entry */
6873 put_elf_reloc(dynsym, got,
6874 got->sh_addr + got->data_ptr - got->data,
6875 R_386_JMP_SLOT,
6876 sym_index);
6877 put32(got->data_ptr, 0);
6878 got->data_ptr += 4;
6880 sym_index++;
6882 /* put dynamic section entries */
6884 dynamic->data_ptr = saved_dynamic_data_ptr;
6885 put_dt(dynamic, DT_HASH, hash->sh_addr);
6886 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
6887 put_dt(dynamic, DT_SYMTAB, dynsym->sh_addr);
6888 put_dt(dynamic, DT_STRSZ, dynstr->data_ptr - dynstr->data);
6889 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
6890 put_dt(dynamic, DT_REL, got->reloc->sh_addr);
6891 put_dt(dynamic, DT_RELSZ, got->reloc->data_ptr - got->reloc->data);
6892 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
6893 put_dt(dynamic, DT_NULL, 0);
6896 ehdr.e_phentsize = sizeof(Elf32_Phdr);
6897 ehdr.e_phnum = phnum;
6898 ehdr.e_phoff = sizeof(Elf32_Ehdr);
6901 /* all other sections come after */
6902 for(i = 1; i < nb_sections; i++) {
6903 s = sections[i];
6904 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
6905 continue;
6906 section_order[sh_order_index++] = i;
6908 file_offset = (file_offset + s->sh_addralign - 1) &
6909 ~(s->sh_addralign - 1);
6910 s->sh_offset = file_offset;
6911 file_offset += s->sh_size;
6914 /* align to 4 */
6915 file_offset = (file_offset + 3) & -4;
6917 /* fill header */
6918 ehdr.e_ident[0] = ELFMAG0;
6919 ehdr.e_ident[1] = ELFMAG1;
6920 ehdr.e_ident[2] = ELFMAG2;
6921 ehdr.e_ident[3] = ELFMAG3;
6922 ehdr.e_ident[4] = ELFCLASS32;
6923 ehdr.e_ident[5] = ELFDATA2LSB;
6924 ehdr.e_ident[6] = EV_CURRENT;
6925 switch(file_type) {
6926 default:
6927 case TCC_FILE_EXE:
6928 ehdr.e_type = ET_EXEC;
6929 break;
6930 case TCC_FILE_DLL:
6931 ehdr.e_type = ET_DYN;
6932 break;
6933 case TCC_FILE_OBJ:
6934 ehdr.e_type = ET_REL;
6935 break;
6937 ehdr.e_machine = EM_386;
6938 ehdr.e_version = EV_CURRENT;
6939 ehdr.e_entry = 0; /* XXX: patch it */
6940 ehdr.e_shoff = file_offset;
6941 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
6942 ehdr.e_shentsize = sizeof(Elf32_Shdr);
6943 ehdr.e_shnum = shnum;
6944 ehdr.e_shstrndx = shnum - 1;
6946 /* write elf file */
6947 if (file_type == TCC_FILE_OBJ)
6948 mode = 0666;
6949 else
6950 mode = 0777;
6951 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
6952 if (fd < 0)
6953 error("could not write '%s'", filename);
6955 f = fdopen(fd, "w");
6956 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
6957 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
6958 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
6959 for(i=1;i<nb_sections;i++) {
6960 s = sections[section_order[i]];
6961 while (offset < s->sh_offset) {
6962 fputc(0, f);
6963 offset++;
6965 size = s->data_ptr - s->data;
6966 fwrite(s->data, 1, size, f);
6967 offset += size;
6969 while (offset < ehdr.e_shoff) {
6970 fputc(0, f);
6971 offset++;
6974 /* output sections */
6975 for(i=0;i<nb_sections;i++) {
6976 sh = &shdr;
6977 memset(sh, 0, sizeof(Elf32_Shdr));
6978 s = sections[i];
6979 if (s) {
6980 sh->sh_name = s->sh_name;
6981 sh->sh_type = s->sh_type;
6982 sh->sh_flags = s->sh_flags;
6983 sh->sh_entsize = s->sh_entsize;
6984 sh->sh_info = s->sh_info;
6985 if (s->link)
6986 sh->sh_link = s->link->sh_num;
6987 sh->sh_addralign = s->sh_addralign;
6988 sh->sh_addr = s->sh_addr;
6989 sh->sh_offset = s->sh_offset;
6990 sh->sh_size = s->sh_size;
6992 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
6994 fclose(f);
6996 free(section_order);
6997 free(phdr);
6998 return 0;
7001 /* print the position in the source file of PC value 'pc' by reading
7002 the stabs debug information */
7003 static void rt_printline(unsigned long wanted_pc)
7005 Stab_Sym *sym, *sym_end;
7006 char func_name[128];
7007 unsigned long func_addr, last_pc, pc;
7008 const char *incl_files[INCLUDE_STACK_SIZE];
7009 int incl_index, len, last_line_num, i;
7010 const char *str, *p;
7012 func_name[0] = '\0';
7013 func_addr = 0;
7014 incl_index = 0;
7015 last_pc = 0xffffffff;
7016 last_line_num = 1;
7017 sym = (Stab_Sym *)stab_section->data + 1;
7018 sym_end = (Stab_Sym *)stab_section->data_ptr;
7019 while (sym < sym_end) {
7020 switch(sym->n_type) {
7021 /* function start or end */
7022 case N_FUN:
7023 if (sym->n_strx == 0) {
7024 func_name[0] = '\0';
7025 func_addr = 0;
7026 } else {
7027 str = stabstr_section->data + sym->n_strx;
7028 p = strchr(str, ':');
7029 if (!p) {
7030 pstrcpy(func_name, sizeof(func_name), str);
7031 } else {
7032 len = p - str;
7033 if (len > sizeof(func_name) - 1)
7034 len = sizeof(func_name) - 1;
7035 memcpy(func_name, str, len);
7036 func_name[len] = '\0';
7038 func_addr = sym->n_value;
7040 break;
7041 /* line number info */
7042 case N_SLINE:
7043 pc = sym->n_value + func_addr;
7044 if (wanted_pc >= last_pc && wanted_pc < pc)
7045 goto found;
7046 last_pc = pc;
7047 last_line_num = sym->n_desc;
7048 break;
7049 /* include files */
7050 case N_BINCL:
7051 str = stabstr_section->data + sym->n_strx;
7052 add_incl:
7053 if (incl_index < INCLUDE_STACK_SIZE) {
7054 incl_files[incl_index++] = str;
7056 break;
7057 case N_EINCL:
7058 if (incl_index > 1)
7059 incl_index--;
7060 break;
7061 case N_SO:
7062 if (sym->n_strx == 0) {
7063 incl_index = 0; /* end of translation unit */
7064 } else {
7065 str = stabstr_section->data + sym->n_strx;
7066 /* do not add path */
7067 len = strlen(str);
7068 if (len > 0 && str[len - 1] != '/')
7069 goto add_incl;
7071 break;
7073 sym++;
7075 /* did not find line number info: */
7076 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
7077 return;
7078 found:
7079 for(i = 0; i < incl_index - 1; i++)
7080 fprintf(stderr, "In file included from %s\n",
7081 incl_files[i]);
7082 if (incl_index > 0) {
7083 fprintf(stderr, "%s:%d: ",
7084 incl_files[incl_index - 1], last_line_num);
7086 if (func_name[0] != '\0') {
7087 fprintf(stderr, "in function '%s()': ", func_name);
7091 /* emit a run time error at position 'pc' */
7092 void rt_error(unsigned long pc, const char *fmt, ...)
7094 va_list ap;
7095 va_start(ap, fmt);
7097 rt_printline(pc);
7098 vfprintf(stderr, fmt, ap);
7099 fprintf(stderr, "\n");
7100 exit(255);
7101 va_end(ap);
7104 #ifndef WIN32
7105 /* signal handler for fatal errors */
7106 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7108 struct ucontext *uc = puc;
7109 unsigned long pc;
7111 #ifdef __i386__
7112 pc = uc->uc_mcontext.gregs[14];
7113 #else
7114 #error please put the right sigcontext field
7115 #endif
7117 switch(signum) {
7118 case SIGFPE:
7119 switch(siginf->si_code) {
7120 case FPE_INTDIV:
7121 case FPE_FLTDIV:
7122 rt_error(pc, "division by zero");
7123 break;
7124 default:
7125 rt_error(pc, "floating point exception");
7126 break;
7128 break;
7129 case SIGBUS:
7130 case SIGSEGV:
7131 rt_error(pc, "dereferencing invalid pointer");
7132 break;
7133 case SIGILL:
7134 rt_error(pc, "illegal instruction");
7135 break;
7136 case SIGABRT:
7137 rt_error(pc, "abort() called");
7138 break;
7139 default:
7140 rt_error(pc, "caught signal %d", signum);
7141 break;
7143 exit(255);
7145 #endif
7147 static void *resolve_sym(const char *sym)
7149 #ifdef CONFIG_TCC_BCHECK
7150 if (do_bounds_check) {
7151 void *ptr;
7152 ptr = bound_resolve_sym(sym);
7153 if (ptr)
7154 return ptr;
7156 #endif
7157 return dlsym(NULL, sym);
7160 static void resolve_extern_syms(void)
7162 unsigned long addr;
7163 Elf32_Sym *sym;
7164 const char *name;
7166 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7167 sym < (Elf32_Sym *)symtab_section->data_ptr;
7168 sym++) {
7169 if (sym->st_shndx == SHN_UNDEF) {
7170 name = symtab_section->link->data + sym->st_name;
7171 addr = (unsigned long)resolve_sym(name);
7172 if (!addr)
7173 error("unresolved external reference '%s'", name);
7174 sym->st_value = addr;
7175 sym->st_shndx = SHN_ABS;
7180 static unsigned long get_sym_val(int sym_index)
7182 unsigned long val;
7183 Elf32_Sym *sym;
7185 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
7186 val = sym->st_value;
7187 if (sym->st_shndx != SHN_ABS)
7188 val += sections[sym->st_shndx]->sh_addr;
7189 return val;
7192 /* relocate sections */
7193 static void relocate_section(Section *s)
7195 Section *sr;
7196 Elf32_Rel *rel;
7197 int type;
7198 unsigned char *ptr;
7199 unsigned long val;
7201 sr = s->reloc;
7202 if (!sr)
7203 return;
7204 for(rel = (Elf32_Rel *)sr->data;
7205 rel < (Elf32_Rel *)sr->data_ptr;
7206 rel++) {
7207 ptr = s->data + rel->r_offset;
7208 val = get_sym_val(ELF32_R_SYM(rel->r_info));
7209 type = ELF32_R_TYPE(rel->r_info);
7210 greloc_patch(ptr, s->sh_addr + rel->r_offset, val, type);
7214 /* relocate all the code and data */
7215 static void relocate_program(void)
7217 Section *s;
7219 /* compute relocation address : section are relocated in place */
7220 for(s = first_section; s != NULL; s = s->next) {
7221 if (s->sh_type == SHT_PROGBITS)
7222 s->sh_addr = (unsigned long)s->data;
7225 /* relocate each section */
7226 for(s = first_section; s != NULL; s = s->next) {
7227 if (s->sh_type == SHT_PROGBITS)
7228 relocate_section(s);
7232 /* launch the compiled program with the given arguments */
7233 int tcc_run(TCCState *s1, int argc, char **argv)
7235 int (*prog_main)(int, char **);
7236 int sym_index;
7238 resolve_extern_syms();
7240 relocate_program();
7242 sym_index = find_elf_sym(symtab_section, "main");
7243 if (!sym_index)
7244 error("main() not defined");
7245 prog_main = (void *)get_sym_val(sym_index);
7247 if (do_debug) {
7248 #ifdef WIN32
7249 error("debug mode currently not available for Windows");
7250 #else
7251 struct sigaction sigact;
7252 /* install TCC signal handlers to print debug info on fatal
7253 runtime errors */
7254 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7255 sigact.sa_sigaction = sig_error;
7256 sigemptyset(&sigact.sa_mask);
7257 sigaction(SIGFPE, &sigact, NULL);
7258 sigaction(SIGILL, &sigact, NULL);
7259 sigaction(SIGSEGV, &sigact, NULL);
7260 sigaction(SIGBUS, &sigact, NULL);
7261 sigaction(SIGABRT, &sigact, NULL);
7262 #endif
7265 #ifdef CONFIG_TCC_BCHECK
7266 if (do_bounds_check) {
7267 int *p, *p_end;
7268 __bound_init();
7269 /* add all known static regions */
7270 p = (int *)bounds_section->data;
7271 p_end = (int *)bounds_section->data_ptr;
7272 while (p < p_end) {
7273 __bound_new_region((void *)p[0], p[1]);
7274 p += 2;
7277 #endif
7279 return (*prog_main)(argc, argv);
7282 TCCState *tcc_new(void)
7284 char *p, *r;
7285 TCCState *s;
7287 s = malloc(sizeof(TCCState));
7288 if (!s)
7289 return NULL;
7291 /* default include paths */
7292 nb_include_paths = 0;
7293 tcc_add_include_path(s, "/usr/include");
7294 tcc_add_include_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7296 /* add all tokens */
7297 tok_ident = TOK_IDENT;
7298 p = tcc_keywords;
7299 while (*p) {
7300 r = p;
7301 while (*r++);
7302 tok_alloc(p, r - p - 1);
7303 p = r;
7306 /* standard defines */
7307 tcc_define_symbol(s, "__STDC__", NULL);
7308 #ifdef __i386__
7309 tcc_define_symbol(s, "__i386__", NULL);
7310 #endif
7311 /* tiny C specific defines */
7312 tcc_define_symbol(s, "__TINYC__", NULL);
7314 /* create standard sections */
7315 nb_sections = 1;
7316 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7317 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7318 /* XXX: should change type to SHT_NOBITS */
7319 bss_section = new_section(".bss", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7321 /* symbols are always generated for linking stage */
7322 symtab_section = new_section(".symtab", SHT_SYMTAB, 0);
7323 symtab_section->sh_entsize = sizeof(Elf32_Sym);
7324 strtab_section = new_section(".strtab", SHT_STRTAB, 0);
7325 put_elf_str(strtab_section, "");
7326 symtab_section->link = strtab_section;
7327 put_elf_sym(symtab_section, 0, 0, 0, 0, 0, NULL);
7329 /* private hash table for extern symbols */
7330 new_section_hash(".hashtab", SHF_PRIVATE,
7331 ELF_SYM_HASH_SIZE, symtab_section);
7332 return s;
7335 void tcc_delete(TCCState *s)
7337 free(s);
7340 int tcc_add_include_path(TCCState *s, const char *pathname)
7342 char *pathname1;
7344 if (nb_include_paths >= INCLUDE_PATHS_MAX)
7345 return -1;
7346 pathname1 = strdup(pathname);
7347 if (!pathname1)
7348 return -1;
7349 include_paths[nb_include_paths++] = pathname1;
7350 return 0;
7353 #if !defined(LIBTCC)
7355 void help(void)
7357 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7358 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
7359 " [-i infile] [-bench] infile [infile_args...]\n"
7360 "\n"
7361 "-Idir : add include path 'dir'\n"
7362 "-Dsym[=val] : define 'sym' with value 'val'\n"
7363 "-Usym : undefine 'sym'\n"
7364 "-llib : link with dynamic library 'lib'\n"
7365 "-g : generate runtime debug info\n"
7366 #ifdef CONFIG_TCC_BCHECK
7367 "-b : compile with built-in memory and bounds checker (implies -g)\n"
7368 #endif
7369 "-i infile : compile infile\n"
7370 "-bench : output compilation statistics\n"
7374 int main(int argc, char **argv)
7376 char *r, *outfile;
7377 int optind, file_type;
7378 TCCState *s;
7380 s = tcc_new();
7381 file_type = TCC_FILE_EXE;
7383 optind = 1;
7384 outfile = NULL;
7385 while (1) {
7386 if (optind >= argc) {
7387 show_help:
7388 help();
7389 return 1;
7391 r = argv[optind];
7392 if (r[0] != '-')
7393 break;
7394 optind++;
7395 if (r[1] == 'I') {
7396 if (tcc_add_include_path(s, r + 2) < 0)
7397 error("too many include paths");
7398 } else if (r[1] == 'D') {
7399 char *sym, *value;
7400 sym = r + 2;
7401 value = strchr(sym, '=');
7402 if (value) {
7403 *value = '\0';
7404 value++;
7406 tcc_define_symbol(s, sym, value);
7407 } else if (r[1] == 'U') {
7408 tcc_undefine_symbol(s, r + 2);
7409 } else if (r[1] == 'l') {
7410 char buf[1024];
7411 snprintf(buf, sizeof(buf), "lib%s.so", r + 2);
7412 tcc_add_dll(s, buf);
7413 } else if (r[1] == 'i') {
7414 if (optind >= argc)
7415 goto show_help;
7416 tcc_compile_file(s, argv[optind++]);
7417 } else if (!strcmp(r + 1, "bench")) {
7418 do_bench = 1;
7419 #ifdef CONFIG_TCC_BCHECK
7420 } else if (r[1] == 'b') {
7421 if (!do_bounds_check) {
7422 do_bounds_check = 1;
7423 /* define symbol */
7424 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7425 /* create bounds sections */
7426 bounds_section = new_section(".bounds",
7427 SHT_PROGBITS, SHF_ALLOC);
7428 lbounds_section = new_section(".lbounds",
7429 SHT_PROGBITS, SHF_ALLOC);
7430 /* debug is implied */
7431 goto debug_opt;
7433 #endif
7434 } else if (r[1] == 'g') {
7435 #ifdef CONFIG_TCC_BCHECK
7436 debug_opt:
7437 #endif
7438 if (!do_debug) {
7439 do_debug = 1;
7441 /* stab symbols */
7442 stab_section = new_section(".stab", SHT_PROGBITS, 0);
7443 stab_section->sh_entsize = sizeof(Stab_Sym);
7444 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
7445 put_elf_str(stabstr_section, "");
7446 stab_section->link = stabstr_section;
7447 /* put first entry */
7448 put_stabs("", 0, 0, 0, 0);
7450 } else
7451 /* the following options are only for testing, so not
7452 documented */
7453 if (r[1] == 'c') {
7454 file_type = TCC_FILE_OBJ;
7455 } else if (!strcmp(r + 1, "shared")) {
7456 file_type = TCC_FILE_DLL;
7457 } else if (r[1] == 'o') {
7458 if (optind >= argc)
7459 goto show_help;
7460 outfile = argv[optind++];
7461 } else {
7462 error("invalid option -- '%s'", r);
7466 tcc_compile_file(s, argv[optind]);
7468 if (do_bench) {
7469 printf("total: %d idents, %d lines, %d bytes\n",
7470 tok_ident - TOK_IDENT, total_lines, total_bytes);
7473 if (outfile) {
7474 tcc_output_file(s, outfile, file_type);
7475 return 0;
7476 } else {
7477 return tcc_run(s, argc - optind, argv + optind);
7481 #endif