more tests
[tinycc.git] / tcc.c
blobc78097dcb208a37445f3961aef218e906456ab00
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 <unistd.h>
29 #include <fcntl.h>
30 #ifndef WIN32
31 #include <sys/ucontext.h>
32 #include <sys/mman.h>
33 #endif
34 #include "elf.h"
35 #include "stab.h"
36 #ifndef CONFIG_TCC_STATIC
37 #include <dlfcn.h>
38 #endif
40 #include "libtcc.h"
42 //#define DEBUG
43 /* preprocessor debug */
44 //#define PP_DEBUG
46 /* target selection */
47 //#define TCC_TARGET_I386 /* i386 code generator */
48 //#define TCC_TARGET_IL /* .NET CLI generator */
50 /* default target is I386 */
51 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
52 #define TCC_TARGET_I386
53 #endif
55 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
56 #define CONFIG_TCC_BCHECK /* enable bound checking code */
57 #endif
59 #ifndef CONFIG_TCC_PREFIX
60 #define CONFIG_TCC_PREFIX "/usr/local"
61 #endif
63 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
64 executables or dlls */
65 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
67 /* amount of virtual memory associated to a section (currently, we do
68 not realloc them) */
69 #define SECTION_VSIZE (1024 * 1024)
71 #define INCLUDE_STACK_SIZE 32
72 #define IFDEF_STACK_SIZE 64
73 #define VSTACK_SIZE 64
74 #define STRING_MAX_SIZE 1024
76 #define TOK_HASH_SIZE 2048 /* must be a power of two */
77 #define TOK_ALLOC_INCR 512 /* must be a power of two */
78 #define SYM_HASH_SIZE 1031
79 #define ELF_SYM_HASH_SIZE 2048
80 #define ELF_DYNSYM_HASH_SIZE 32
82 /* token symbol management */
83 typedef struct TokenSym {
84 struct TokenSym *hash_next;
85 int tok; /* token number */
86 int len;
87 char str[1];
88 } TokenSym;
90 /* constant value */
91 typedef union CValue {
92 long double ld;
93 double d;
94 float f;
95 int i;
96 unsigned int ui;
97 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
98 long long ll;
99 unsigned long long ull;
100 struct TokenSym *ts;
101 struct Sym *sym;
102 void *ptr;
103 int tab[1];
104 } CValue;
106 /* value on stack */
107 typedef struct SValue {
108 int t; /* type */
109 unsigned short r; /* register + flags */
110 unsigned short r2; /* second register, used for 'long long'
111 type. If not used, set to VT_CONST */
112 CValue c; /* constant, if VT_CONST */
113 } SValue;
115 /* symbol management */
116 typedef struct Sym {
117 int v; /* symbol token */
118 int t; /* associated type */
119 int r; /* associated register */
120 int c; /* associated number */
121 struct Sym *next; /* next related symbol */
122 struct Sym *prev; /* prev symbol in stack */
123 struct Sym *hash_next; /* next symbol in hash table */
124 } Sym;
126 typedef struct SymStack {
127 struct Sym *top;
128 struct Sym *hash[SYM_HASH_SIZE];
129 } SymStack;
131 /* section definition */
132 /* XXX: use directly ELF structure for parameters ? */
133 /* special flag to indicate that the section should not be linked to
134 the other ones */
135 #define SHF_PRIVATE 0x80000000
137 typedef struct Section {
138 unsigned long data_offset; /* current data offset */
139 unsigned char *data; /* section data */
140 int sh_name; /* elf section name (only used during output) */
141 int sh_num; /* elf section number */
142 int sh_type; /* elf section type */
143 int sh_flags; /* elf section flags */
144 int sh_info; /* elf section info */
145 int sh_addralign; /* elf section alignment */
146 int sh_entsize; /* elf entry size */
147 unsigned long sh_size; /* section size (only used during output) */
148 unsigned long sh_addr; /* address at which the section is relocated */
149 unsigned long sh_offset; /* address at which the section is relocated */
150 struct Section *link; /* link to another section */
151 struct Section *reloc; /* corresponding section for relocation, if any */
152 struct Section *hash; /* hash table for symbols */
153 struct Section *next;
154 char name[64]; /* section name */
155 } Section;
157 typedef struct DLLReference {
158 int level;
159 char name[1];
160 } DLLReference;
162 /* GNUC attribute definition */
163 typedef struct AttributeDef {
164 int aligned;
165 Section *section;
166 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
167 } AttributeDef;
169 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
170 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
171 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
173 /* stored in 'Sym.c' field */
174 #define FUNC_NEW 1 /* ansi function prototype */
175 #define FUNC_OLD 2 /* old function prototype */
176 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
178 /* stored in 'Sym.r' field */
179 #define FUNC_CDECL 0 /* standard c call */
180 #define FUNC_STDCALL 1 /* pascal c call */
182 /* field 'Sym.t' for macros */
183 #define MACRO_OBJ 0 /* object like macro */
184 #define MACRO_FUNC 1 /* function like macro */
186 /* field 'Sym.t' for labels */
187 #define LABEL_FORWARD 1 /* label is forward defined */
189 /* type_decl() types */
190 #define TYPE_ABSTRACT 1 /* type without variable */
191 #define TYPE_DIRECT 2 /* type with variable */
193 #define IO_BUF_SIZE 8192
195 typedef struct BufferedFile {
196 unsigned char *buf_ptr;
197 unsigned char *buf_end;
198 int fd;
199 int line_num; /* current line number - here to simply code */
200 char filename[1024]; /* current filename - here to simplify code */
201 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
202 } BufferedFile;
204 #define CH_EOB 0 /* end of buffer or '\0' char in file */
205 #define CH_EOF (-1) /* end of file */
207 /* parsing state (used to save parser state to reparse part of the
208 source several times) */
209 typedef struct ParseState {
210 int *macro_ptr;
211 int line_num;
212 int tok;
213 CValue tokc;
214 } ParseState;
216 /* used to record tokens */
217 typedef struct TokenString {
218 int *str;
219 int len;
220 int last_line_num;
221 } TokenString;
223 /* parser */
224 struct BufferedFile *file;
225 int ch, ch1, tok, tok1;
226 CValue tokc, tok1c;
227 int return_linefeed; /* if true, line feed is returned as a token */
229 /* sections */
230 Section **sections;
231 int nb_sections; /* number of sections, including first dummy section */
232 Section *text_section, *data_section, *bss_section; /* predefined sections */
233 Section *cur_text_section; /* current section where function code is
234 generated */
235 /* bound check related sections */
236 Section *bounds_section; /* contains global data bound description */
237 Section *lbounds_section; /* contains local data bound description */
238 /* symbol sections */
239 Section *symtab_section, *strtab_section;
240 /* temporary dynamic symbol sections (for dll loading) */
241 Section *dynsymtab_section, *dynstrtab_section;
242 /* exported dynamic symbol section */
243 Section *dynsym;
244 /* got handling */
245 Section *got;
246 unsigned long *got_offsets;
247 int nb_got_offsets;
248 int nb_plt_entries;
251 /* array of all loaded dlls (including those referenced by loaded
252 dlls) */
253 DLLReference **loaded_dlls;
254 int nb_loaded_dlls;
256 /* debug sections */
257 Section *stab_section, *stabstr_section;
259 char **library_paths;
260 int nb_library_paths;
262 /* loc : local variable index
263 ind : output code index
264 rsym: return symbol
265 anon_sym: anonymous symbol index
267 int rsym, anon_sym,
268 prog, ind, loc, const_wanted;
269 int global_expr; /* true if compound literals must be allocated
270 globally (used during initializers parsing */
271 int func_vt, func_vc; /* current function return type (used by
272 return instruction) */
273 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
274 int tok_ident;
275 TokenSym **table_ident;
276 TokenSym *hash_ident[TOK_HASH_SIZE];
277 char token_buf[STRING_MAX_SIZE + 1];
278 char *funcname;
279 SymStack define_stack, global_stack, local_stack, label_stack;
281 SValue vstack[VSTACK_SIZE], *vtop;
282 int *macro_ptr, *macro_ptr_allocated;
283 BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr;
284 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
285 char **include_paths;
286 int nb_include_paths;
287 int char_pointer_type;
288 int func_old_type;
290 /* compile with debug symbol (and use them if error during execution) */
291 int do_debug = 0;
293 /* compile with built-in memory and bounds checker */
294 int do_bounds_check = 0;
296 /* display benchmark infos */
297 int do_bench = 0;
298 int total_lines;
299 int total_bytes;
301 /* use GNU C extensions */
302 int gnu_ext = 1;
304 /* use Tiny C extensions */
305 int tcc_ext = 1;
307 /* if true, static linking is performed */
308 int static_link = 0;
310 /* give the path of the tcc libraries */
311 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
313 struct TCCState {
314 int output_type;
317 /* The current value can be: */
318 #define VT_VALMASK 0x00ff
319 #define VT_CONST 0x00f0 /* constant in vc
320 (must be first non register value) */
321 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
322 #define VT_LOCAL 0x00f2 /* offset on stack */
323 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
324 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
325 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
326 #define VT_LVAL 0x0100 /* var is an lvalue */
327 #define VT_SYM 0x0200 /* a symbol value is added */
328 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
329 char/short stored in integer registers) */
330 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
331 dereferencing value */
332 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
333 bounding function call point is in vc */
334 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
335 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
336 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
337 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
339 /* types */
340 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
342 #define VT_INT 0 /* integer type */
343 #define VT_BYTE 1 /* signed byte type */
344 #define VT_SHORT 2 /* short type */
345 #define VT_VOID 3 /* void type */
346 #define VT_PTR 4 /* pointer */
347 #define VT_ENUM 5 /* enum definition */
348 #define VT_FUNC 6 /* function type */
349 #define VT_STRUCT 7 /* struct/union definition */
350 #define VT_FLOAT 8 /* IEEE float */
351 #define VT_DOUBLE 9 /* IEEE double */
352 #define VT_LDOUBLE 10 /* IEEE long double */
353 #define VT_BOOL 11 /* ISOC99 boolean type */
354 #define VT_LLONG 12 /* 64 bit integer */
355 #define VT_LONG 13 /* long integer (NEVER USED as type, only
356 during parsing) */
357 #define VT_BTYPE 0x000f /* mask for basic type */
358 #define VT_UNSIGNED 0x0010 /* unsigned type */
359 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
360 #define VT_BITFIELD 0x0040 /* bitfield modifier */
362 /* storage */
363 #define VT_EXTERN 0x00000080 /* extern definition */
364 #define VT_STATIC 0x00000100 /* static variable */
365 #define VT_TYPEDEF 0x00000200 /* typedef definition */
367 /* type mask (except storage) */
368 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
370 /* token values */
372 /* warning: the following compare tokens depend on i386 asm code */
373 #define TOK_ULT 0x92
374 #define TOK_UGE 0x93
375 #define TOK_EQ 0x94
376 #define TOK_NE 0x95
377 #define TOK_ULE 0x96
378 #define TOK_UGT 0x97
379 #define TOK_LT 0x9c
380 #define TOK_GE 0x9d
381 #define TOK_LE 0x9e
382 #define TOK_GT 0x9f
384 #define TOK_LAND 0xa0
385 #define TOK_LOR 0xa1
387 #define TOK_DEC 0xa2
388 #define TOK_MID 0xa3 /* inc/dec, to void constant */
389 #define TOK_INC 0xa4
390 #define TOK_UDIV 0xb0 /* unsigned division */
391 #define TOK_UMOD 0xb1 /* unsigned modulo */
392 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
393 #define TOK_CINT 0xb3 /* number in tokc */
394 #define TOK_CCHAR 0xb4 /* char constant in tokc */
395 #define TOK_STR 0xb5 /* pointer to string in tokc */
396 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
397 #define TOK_LCHAR 0xb7
398 #define TOK_LSTR 0xb8
399 #define TOK_CFLOAT 0xb9 /* float constant */
400 #define TOK_LINENUM 0xba /* line number info */
401 #define TOK_CDOUBLE 0xc0 /* double constant */
402 #define TOK_CLDOUBLE 0xc1 /* long double constant */
403 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
404 #define TOK_ADDC1 0xc3 /* add with carry generation */
405 #define TOK_ADDC2 0xc4 /* add with carry use */
406 #define TOK_SUBC1 0xc5 /* add with carry generation */
407 #define TOK_SUBC2 0xc6 /* add with carry use */
408 #define TOK_CUINT 0xc8 /* unsigned int constant */
409 #define TOK_CLLONG 0xc9 /* long long constant */
410 #define TOK_CULLONG 0xca /* unsigned long long constant */
411 #define TOK_ARROW 0xcb
412 #define TOK_DOTS 0xcc /* three dots */
413 #define TOK_SHR 0xcd /* unsigned shift right */
415 #define TOK_SHL 0x01 /* shift left */
416 #define TOK_SAR 0x02 /* signed shift right */
418 /* assignement operators : normal operator or 0x80 */
419 #define TOK_A_MOD 0xa5
420 #define TOK_A_AND 0xa6
421 #define TOK_A_MUL 0xaa
422 #define TOK_A_ADD 0xab
423 #define TOK_A_SUB 0xad
424 #define TOK_A_DIV 0xaf
425 #define TOK_A_XOR 0xde
426 #define TOK_A_OR 0xfc
427 #define TOK_A_SHL 0x81
428 #define TOK_A_SAR 0x82
430 #define TOK_EOF (-1) /* end of file */
431 #define TOK_LINEFEED 10 /* line feed */
433 /* all identificators and strings have token above that */
434 #define TOK_IDENT 256
436 enum {
437 TOK_INT = TOK_IDENT,
438 TOK_VOID,
439 TOK_CHAR,
440 TOK_IF,
441 TOK_ELSE,
442 TOK_WHILE,
443 TOK_BREAK,
444 TOK_RETURN,
445 TOK_FOR,
446 TOK_EXTERN,
447 TOK_STATIC,
448 TOK_UNSIGNED,
449 TOK_GOTO,
450 TOK_DO,
451 TOK_CONTINUE,
452 TOK_SWITCH,
453 TOK_CASE,
455 /* ignored types Must have contiguous values */
456 TOK_CONST,
457 TOK_VOLATILE,
458 TOK_LONG,
459 TOK_REGISTER,
460 TOK_SIGNED,
461 TOK___SIGNED__, /* gcc keyword */
462 TOK_AUTO,
463 TOK_INLINE,
464 TOK___INLINE__, /* gcc keyword */
465 TOK_RESTRICT,
467 /* unsupported type */
468 TOK_FLOAT,
469 TOK_DOUBLE,
470 TOK_BOOL,
472 TOK_SHORT,
473 TOK_STRUCT,
474 TOK_UNION,
475 TOK_TYPEDEF,
476 TOK_DEFAULT,
477 TOK_ENUM,
478 TOK_SIZEOF,
479 TOK___ATTRIBUTE__,
481 /* preprocessor only */
482 TOK_UIDENT, /* first "user" ident (not keyword) */
483 TOK_DEFINE = TOK_UIDENT,
484 TOK_INCLUDE,
485 TOK_IFDEF,
486 TOK_IFNDEF,
487 TOK_ELIF,
488 TOK_ENDIF,
489 TOK_DEFINED,
490 TOK_UNDEF,
491 TOK_ERROR,
492 TOK_LINE,
493 TOK___LINE__,
494 TOK___FILE__,
495 TOK___DATE__,
496 TOK___TIME__,
497 TOK___VA_ARGS__,
499 /* special identifiers */
500 TOK___FUNC__,
501 TOK_MAIN,
502 #define DEF(id, str) id,
503 #include "tcctok.h"
504 #undef DEF
507 char *tcc_keywords =
508 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
509 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
510 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
511 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
512 "sizeof\0__attribute__\0"
513 /* the following are not keywords. They are included to ease parsing */
514 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
515 "defined\0undef\0error\0line\0"
516 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
517 "__func__\0main\0"
518 /* builtin functions */
519 #define DEF(id, str) str "\0"
520 #include "tcctok.h"
521 #undef DEF
524 #ifdef WIN32
525 #define snprintf _snprintf
526 #endif
528 #if defined(WIN32) || defined(TCC_UCLIBC)
529 /* currently incorrect */
530 long double strtold(const char *nptr, char **endptr)
532 return (long double)strtod(nptr, endptr);
534 float strtof(const char *nptr, char **endptr)
536 return (float)strtod(nptr, endptr);
538 #else
539 /* XXX: need to define this to use them in non ISOC99 context */
540 extern float strtof (const char *__nptr, char **__endptr);
541 extern long double strtold (const char *__nptr, char **__endptr);
542 #endif
544 static char *pstrcpy(char *buf, int buf_size, const char *s);
545 static char *pstrcat(char *buf, int buf_size, const char *s);
547 void sum(int l);
548 void next(void);
549 void next_nomacro(void);
550 int expr_const(void);
551 void expr_eq(void);
552 void gexpr(void);
553 void decl(int l);
554 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only);
555 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
556 int v, int scope);
557 int gv(int rc);
558 void gv2(int rc1, int rc2);
559 void move_reg(int r, int s);
560 void save_regs(int n);
561 void save_reg(int r);
562 void vpop(void);
563 void vswap(void);
564 void vdup(void);
565 int get_reg(int rc);
567 void macro_subst(TokenString *tok_str,
568 Sym **nested_list, int *macro_str);
569 int save_reg_forced(int r);
570 void gen_op(int op);
571 void force_charshort_cast(int t);
572 void gen_cast(int t);
573 void vstore(void);
574 Sym *sym_find(int v);
575 Sym *sym_push(int v, int t, int r, int c);
577 /* type handling */
578 int type_size(int t, int *a);
579 int pointed_type(int t);
580 int pointed_size(int t);
581 int is_compatible_types(int t1, int t2);
582 int parse_btype(int *type_ptr, AttributeDef *ad);
583 int type_decl(AttributeDef *ad, int *v, int t, int td);
585 void error(const char *fmt, ...);
586 void rt_error(unsigned long pc, const char *fmt, ...);
587 void vpushi(int v);
588 void vset(int t, int r, int v);
589 void type_to_str(char *buf, int buf_size,
590 int t, const char *varstr);
591 char *get_tok_str(int v, CValue *cv);
592 Sym *external_sym(int v, int u, int r);
593 static Sym *get_sym_ref(int t, Section *sec,
594 unsigned long offset, unsigned long size);
596 /* section generation */
597 static void *section_ptr(Section *sec, unsigned long size);
598 static void *section_ptr_add(Section *sec, unsigned long size);
599 void put_extern_sym(Sym *sym, Section *section, unsigned long value);
600 void greloc(Section *s, Sym *sym, unsigned long addr, int type);
601 static int put_elf_str(Section *s, const char *sym);
602 static int put_elf_sym(Section *s,
603 unsigned long value, unsigned long size,
604 int info, int other, int shndx, const char *name);
605 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
606 int type, int symbol);
607 static void put_stabs(const char *str, int type, int other, int desc,
608 unsigned long value);
609 static void put_stabs_r(const char *str, int type, int other, int desc,
610 unsigned long value, Section *sec, int sym_index);
611 static void put_stabn(int type, int other, int desc, int value);
612 static void put_stabd(int type, int other, int desc);
613 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
615 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
616 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
617 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
619 /* true if float/double/long double type */
620 static inline int is_float(int t)
622 int bt;
623 bt = t & VT_BTYPE;
624 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
627 #ifdef TCC_TARGET_I386
628 #include "i386-gen.c"
629 #endif
630 #ifdef TCC_TARGET_IL
631 #include "il-gen.c"
632 #endif
634 #ifdef CONFIG_TCC_STATIC
636 #define RTLD_LAZY 0x001
637 #define RTLD_NOW 0x002
638 #define RTLD_GLOBAL 0x100
640 /* dummy function for profiling */
641 void *dlopen(const char *filename, int flag)
643 return NULL;
646 const char *dlerror(void)
648 return "error";
651 typedef struct TCCSyms {
652 char *str;
653 void *ptr;
654 } TCCSyms;
656 #define TCCSYM(a) { #a, &a, },
658 /* add the symbol you want here if no dynamic linking is done */
659 static TCCSyms tcc_syms[] = {
660 TCCSYM(printf)
661 TCCSYM(fprintf)
662 TCCSYM(fopen)
663 TCCSYM(fclose)
664 { NULL, NULL },
667 void *dlsym(void *handle, const char *symbol)
669 TCCSyms *p;
670 p = tcc_syms;
671 while (p->str != NULL) {
672 if (!strcmp(p->str, symbol))
673 return p->ptr;
674 p++;
676 return NULL;
679 #endif
681 /********************************************************/
683 /* we use our own 'finite' function to avoid potential problems with
684 non standard math libs */
685 /* XXX: endianness dependant */
686 int ieee_finite(double d)
688 int *p = (int *)&d;
689 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
692 /* copy a string and truncate it. */
693 static char *pstrcpy(char *buf, int buf_size, const char *s)
695 char *q, *q_end;
696 int c;
698 if (buf_size > 0) {
699 q = buf;
700 q_end = buf + buf_size - 1;
701 while (q < q_end) {
702 c = *s++;
703 if (c == '\0')
704 break;
705 *q++ = c;
707 *q = '\0';
709 return buf;
712 /* strcat and truncate. */
713 static char *pstrcat(char *buf, int buf_size, const char *s)
715 int len;
716 len = strlen(buf);
717 if (len < buf_size)
718 pstrcpy(buf + len, buf_size - len, s);
719 return buf;
722 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
724 int nb, nb_alloc;
725 void **pp;
727 nb = *nb_ptr;
728 pp = *ptab;
729 /* every power of two we double array size */
730 if ((nb & (nb - 1)) == 0) {
731 if (!nb)
732 nb_alloc = 1;
733 else
734 nb_alloc = nb * 2;
735 pp = realloc(pp, nb_alloc * sizeof(void *));
736 if (!pp)
737 error("memory full");
738 *ptab = pp;
740 pp[nb++] = data;
741 *nb_ptr = nb;
744 Section *new_section(const char *name, int sh_type, int sh_flags)
746 Section *sec;
747 void *data;
749 sec = malloc(sizeof(Section));
750 if (!sec)
751 error("memory full");
752 memset(sec, 0, sizeof(Section));
753 pstrcpy(sec->name, sizeof(sec->name), name);
754 sec->sh_type = sh_type;
755 sec->sh_flags = sh_flags;
756 switch(sh_type) {
757 case SHT_HASH:
758 case SHT_REL:
759 case SHT_DYNSYM:
760 case SHT_SYMTAB:
761 case SHT_DYNAMIC:
762 sec->sh_addralign = 4;
763 break;
764 case SHT_STRTAB:
765 sec->sh_addralign = 1;
766 break;
767 default:
768 sec->sh_addralign = 32; /* default conservative alignment */
769 break;
771 #ifdef WIN32
772 /* XXX: currently, a single malloc */
773 data = malloc(SECTION_VSIZE);
774 if (data == NULL)
775 error("could not alloc section '%s'", name);
776 #else
777 data = mmap(NULL, SECTION_VSIZE,
778 PROT_EXEC | PROT_READ | PROT_WRITE,
779 MAP_PRIVATE | MAP_ANONYMOUS,
780 -1, 0);
781 if (data == (void *)(-1))
782 error("could not mmap section '%s'", name);
783 #endif
784 sec->data = data;
785 sec->data_offset = 0;
787 /* only add section if not private */
788 if (!(sh_flags & SHF_PRIVATE)) {
789 sec->sh_num = nb_sections;
790 dynarray_add((void ***)&sections, &nb_sections, sec);
792 return sec;
795 /* reserve at least 'size' bytes in section 'sec' from sec->data_offset */
796 static void *section_ptr(Section *sec, unsigned long size)
798 return sec->data + sec->data_offset;
801 static void *section_ptr_add(Section *sec, unsigned long size)
803 void *ptr;
804 ptr = sec->data + sec->data_offset;
805 sec->data_offset += size;
806 return ptr;
809 /* return a reference to a section, and create it if it does not
810 exists */
811 Section *find_section(const char *name)
813 Section *sec;
814 int i;
815 for(i = 1; i < nb_sections; i++) {
816 sec = sections[i];
817 if (!strcmp(name, sec->name))
818 return sec;
820 /* sections are created as PROGBITS */
821 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
824 /* add a new relocation entry to symbol 'sym' in section 's' */
825 void greloc(Section *s, Sym *sym, unsigned long offset, int type)
827 if (!sym->c)
828 put_extern_sym(sym, NULL, 0);
829 /* now we can add ELF relocation info */
830 put_elf_reloc(symtab_section, s, offset, type, sym->c);
833 static inline int isid(int c)
835 return (c >= 'a' && c <= 'z') ||
836 (c >= 'A' && c <= 'Z') ||
837 c == '_';
840 static inline int isnum(int c)
842 return c >= '0' && c <= '9';
845 static inline int toup(int c)
847 if (ch >= 'a' && ch <= 'z')
848 return ch - 'a' + 'A';
849 else
850 return ch;
853 void printline(void)
855 BufferedFile **f;
857 if (file) {
858 for(f = include_stack; f < include_stack_ptr; f++)
859 fprintf(stderr, "In file included from %s:%d:\n",
860 (*f)->filename, (*f)->line_num);
861 if (file->line_num > 0) {
862 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
863 } else {
864 fprintf(stderr, "%s: ", file->filename);
866 } else {
867 fprintf(stderr, "tcc: ");
871 void error(const char *fmt, ...)
873 va_list ap;
874 va_start(ap, fmt);
875 printline();
876 vfprintf(stderr, fmt, ap);
877 fprintf(stderr, "\n");
878 exit(1);
879 va_end(ap);
882 void expect(const char *msg)
884 error("%s expected", msg);
887 void warning(const char *fmt, ...)
889 va_list ap;
891 va_start(ap, fmt);
892 printline();
893 fprintf(stderr, "warning: ");
894 vfprintf(stderr, fmt, ap);
895 fprintf(stderr, "\n");
896 va_end(ap);
899 void skip(int c)
901 if (tok != c)
902 error("'%c' expected", c);
903 next();
906 void test_lvalue(void)
908 if (!(vtop->r & VT_LVAL))
909 expect("lvalue");
912 TokenSym *tok_alloc(const char *str, int len)
914 TokenSym *ts, **pts, **ptable;
915 int h, i;
917 if (len <= 0)
918 len = strlen(str);
919 h = 1;
920 for(i=0;i<len;i++)
921 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
923 pts = &hash_ident[h];
924 while (1) {
925 ts = *pts;
926 if (!ts)
927 break;
928 if (ts->len == len && !memcmp(ts->str, str, len))
929 return ts;
930 pts = &(ts->hash_next);
933 if (tok_ident >= SYM_FIRST_ANOM)
934 error("memory full");
936 /* expand token table if needed */
937 i = tok_ident - TOK_IDENT;
938 if ((i % TOK_ALLOC_INCR) == 0) {
939 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
940 if (!ptable)
941 error("memory full");
942 table_ident = ptable;
945 ts = malloc(sizeof(TokenSym) + len);
946 if (!ts)
947 error("memory full");
948 table_ident[i] = ts;
949 ts->tok = tok_ident++;
950 ts->len = len;
951 ts->hash_next = NULL;
952 memcpy(ts->str, str, len + 1);
953 *pts = ts;
954 return ts;
957 void add_char(char **pp, int c)
959 char *p;
960 p = *pp;
961 if (c == '\'' || c == '\"' || c == '\\') {
962 /* XXX: could be more precise if char or string */
963 *p++ = '\\';
965 if (c >= 32 && c <= 126) {
966 *p++ = c;
967 } else {
968 *p++ = '\\';
969 if (c == '\n') {
970 *p++ = 'n';
971 } else {
972 *p++ = '0' + ((c >> 6) & 7);
973 *p++ = '0' + ((c >> 3) & 7);
974 *p++ = '0' + (c & 7);
977 *pp = p;
980 /* XXX: buffer overflow */
981 char *get_tok_str(int v, CValue *cv)
983 static char buf[STRING_MAX_SIZE + 1];
984 TokenSym *ts;
985 char *p;
986 int i;
988 if (v == TOK_CINT || v == TOK_CUINT) {
989 sprintf(buf, "%u", cv->ui);
990 return buf;
991 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
992 p = buf;
993 *p++ = '\'';
994 add_char(&p, cv->i);
995 *p++ = '\'';
996 *p = '\0';
997 return buf;
998 } else if (v == TOK_STR || v == TOK_LSTR) {
999 ts = cv->ts;
1000 p = buf;
1001 *p++ = '\"';
1002 for(i=0;i<ts->len;i++)
1003 add_char(&p, ts->str[i]);
1004 *p++ = '\"';
1005 *p = '\0';
1006 return buf;
1007 } else if (v < TOK_IDENT) {
1008 p = buf;
1009 *p++ = v;
1010 *p = '\0';
1011 return buf;
1012 } else if (v < tok_ident) {
1013 return table_ident[v - TOK_IDENT]->str;
1014 } else if (v >= SYM_FIRST_ANOM) {
1015 /* special name for anonymous symbol */
1016 sprintf(buf, "L.%u", v - SYM_FIRST_ANOM);
1017 return buf;
1018 } else {
1019 /* should never happen */
1020 return NULL;
1024 /* push, without hashing */
1025 Sym *sym_push2(Sym **ps, int v, int t, int c)
1027 Sym *s;
1028 s = malloc(sizeof(Sym));
1029 if (!s)
1030 error("memory full");
1031 s->v = v;
1032 s->t = t;
1033 s->c = c;
1034 s->next = NULL;
1035 /* add in stack */
1036 s->prev = *ps;
1037 *ps = s;
1038 return s;
1041 /* find a symbol and return its associated structure. 's' is the top
1042 of the symbol stack */
1043 Sym *sym_find2(Sym *s, int v)
1045 while (s) {
1046 if (s->v == v)
1047 return s;
1048 s = s->prev;
1050 return NULL;
1053 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1055 /* find a symbol and return its associated structure. 'st' is the
1056 symbol stack */
1057 Sym *sym_find1(SymStack *st, int v)
1059 Sym *s;
1061 s = st->hash[HASH_SYM(v)];
1062 while (s) {
1063 if (s->v == v)
1064 return s;
1065 s = s->hash_next;
1067 return NULL;
1070 Sym *sym_push1(SymStack *st, int v, int t, int c)
1072 Sym *s, **ps;
1073 s = sym_push2(&st->top, v, t, c);
1074 /* add in hash table */
1075 if (v) {
1076 ps = &st->hash[HASH_SYM(v)];
1077 s->hash_next = *ps;
1078 *ps = s;
1080 return s;
1083 /* find a symbol in the right symbol space */
1084 Sym *sym_find(int v)
1086 Sym *s;
1087 s = sym_find1(&local_stack, v);
1088 if (!s)
1089 s = sym_find1(&global_stack, v);
1090 return s;
1093 /* push a given symbol on the symbol stack */
1094 Sym *sym_push(int v, int t, int r, int c)
1096 Sym *s;
1097 if (local_stack.top)
1098 s = sym_push1(&local_stack, v, t, c);
1099 else
1100 s = sym_push1(&global_stack, v, t, c);
1101 s->r = r;
1102 return s;
1105 /* pop symbols until top reaches 'b' */
1106 void sym_pop(SymStack *st, Sym *b)
1108 Sym *s, *ss;
1110 s = st->top;
1111 while(s != b) {
1112 ss = s->prev;
1113 /* free hash table entry, except if symbol was freed (only
1114 used for #undef symbols) */
1115 if (s->v)
1116 st->hash[HASH_SYM(s->v)] = s->hash_next;
1117 free(s);
1118 s = ss;
1120 st->top = b;
1123 /* undefined a hashed symbol (used for #undef). Its name is set to
1124 zero */
1125 void sym_undef(SymStack *st, Sym *s)
1127 Sym **ss;
1128 ss = &st->hash[HASH_SYM(s->v)];
1129 while (*ss != NULL) {
1130 if (*ss == s)
1131 break;
1132 ss = &(*ss)->hash_next;
1134 *ss = s->hash_next;
1135 s->v = 0;
1138 /* I/O layer */
1140 BufferedFile *tcc_open(const char *filename)
1142 int fd;
1143 BufferedFile *bf;
1145 fd = open(filename, O_RDONLY);
1146 if (fd < 0)
1147 return NULL;
1148 bf = malloc(sizeof(BufferedFile));
1149 if (!bf) {
1150 close(fd);
1151 return NULL;
1153 bf->fd = fd;
1154 bf->buf_ptr = bf->buffer;
1155 bf->buf_end = bf->buffer;
1156 bf->buffer[0] = CH_EOB; /* put eob symbol */
1157 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1158 bf->line_num = 1;
1159 // printf("opening '%s'\n", filename);
1160 return bf;
1163 void tcc_close(BufferedFile *bf)
1165 total_lines += bf->line_num;
1166 close(bf->fd);
1167 free(bf);
1170 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1171 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1173 /* fill input buffer and return next char */
1174 int tcc_getc_slow(BufferedFile *bf)
1176 int len;
1177 /* only tries to read if really end of buffer */
1178 if (bf->buf_ptr >= bf->buf_end) {
1179 if (bf->fd != -1) {
1180 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1181 if (len < 0)
1182 len = 0;
1183 } else {
1184 len = 0;
1186 total_bytes += len;
1187 bf->buf_ptr = bf->buffer;
1188 bf->buf_end = bf->buffer + len;
1189 *bf->buf_end = CH_EOB;
1191 if (bf->buf_ptr < bf->buf_end) {
1192 return *bf->buf_ptr++;
1193 } else {
1194 bf->buf_ptr = bf->buf_end;
1195 return CH_EOF;
1199 /* no need to put that inline */
1200 void handle_eob(void)
1202 for(;;) {
1203 ch1 = tcc_getc_slow(file);
1204 if (ch1 != CH_EOF)
1205 return;
1207 if (include_stack_ptr == include_stack)
1208 return;
1209 /* add end of include file debug info */
1210 if (do_debug) {
1211 put_stabd(N_EINCL, 0, 0);
1213 /* pop include stack */
1214 tcc_close(file);
1215 include_stack_ptr--;
1216 file = *include_stack_ptr;
1220 /* read next char from current input file */
1221 static inline void inp(void)
1223 ch1 = TCC_GETC(file);
1224 /* end of buffer/file handling */
1225 if (ch1 == CH_EOB)
1226 handle_eob();
1227 if (ch1 == '\n')
1228 file->line_num++;
1229 // printf("ch1=%c 0x%x\n", ch1, ch1);
1232 /* input with '\\n' handling */
1233 static inline void minp(void)
1235 redo:
1236 ch = ch1;
1237 inp();
1238 if (ch == '\\' && ch1 == '\n') {
1239 inp();
1240 goto redo;
1242 //printf("ch=%c 0x%x\n", ch, ch);
1246 /* same as minp, but also skip comments */
1247 void cinp(void)
1249 int c;
1251 if (ch1 == '/') {
1252 inp();
1253 if (ch1 == '/') {
1254 /* single line C++ comments */
1255 inp();
1256 while (ch1 != '\n' && ch1 != -1)
1257 inp();
1258 inp();
1259 ch = ' '; /* return space */
1260 } else if (ch1 == '*') {
1261 /* C comments */
1262 inp();
1263 while (ch1 != -1) {
1264 c = ch1;
1265 inp();
1266 if (c == '*' && ch1 == '/') {
1267 inp();
1268 ch = ' '; /* return space */
1269 break;
1272 } else {
1273 ch = '/';
1275 } else {
1276 minp();
1280 void skip_spaces(void)
1282 while (ch == ' ' || ch == '\t')
1283 cinp();
1286 /* skip block of text until #else, #elif or #endif. skip also pairs of
1287 #if/#endif */
1288 void preprocess_skip(void)
1290 int a;
1291 a = 0;
1292 while (1) {
1293 while (ch != '\n') {
1294 if (ch == -1)
1295 expect("#endif");
1296 cinp();
1298 cinp();
1299 skip_spaces();
1300 if (ch == '#') {
1301 cinp();
1302 next_nomacro();
1303 if (a == 0 &&
1304 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1305 break;
1306 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1307 a++;
1308 else if (tok == TOK_ENDIF)
1309 a--;
1314 /* ParseState handling */
1316 /* XXX: currently, no include file info is stored. Thus, we cannot display
1317 accurate messages if the function or data definition spans multiple
1318 files */
1320 /* save current parse state in 's' */
1321 void save_parse_state(ParseState *s)
1323 s->line_num = file->line_num;
1324 s->macro_ptr = macro_ptr;
1325 s->tok = tok;
1326 s->tokc = tokc;
1329 /* restore parse state from 's' */
1330 void restore_parse_state(ParseState *s)
1332 file->line_num = s->line_num;
1333 macro_ptr = s->macro_ptr;
1334 tok = s->tok;
1335 tokc = s->tokc;
1338 /* return the number of additionnal 'ints' necessary to store the
1339 token */
1340 static inline int tok_ext_size(int t)
1342 switch(t) {
1343 /* 4 bytes */
1344 case TOK_CINT:
1345 case TOK_CUINT:
1346 case TOK_CCHAR:
1347 case TOK_LCHAR:
1348 case TOK_STR:
1349 case TOK_LSTR:
1350 case TOK_CFLOAT:
1351 case TOK_LINENUM:
1352 return 1;
1353 case TOK_CDOUBLE:
1354 case TOK_CLLONG:
1355 case TOK_CULLONG:
1356 return 2;
1357 case TOK_CLDOUBLE:
1358 return LDOUBLE_SIZE / 4;
1359 default:
1360 return 0;
1364 /* token string handling */
1366 static inline void tok_str_new(TokenString *s)
1368 s->str = NULL;
1369 s->len = 0;
1370 s->last_line_num = -1;
1373 static void tok_str_add(TokenString *s, int t)
1375 int len, *str;
1377 len = s->len;
1378 str = s->str;
1379 if ((len & 63) == 0) {
1380 str = realloc(str, (len + 64) * sizeof(int));
1381 if (!str)
1382 return;
1383 s->str = str;
1385 str[len++] = t;
1386 s->len = len;
1389 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1391 int n, i;
1392 tok_str_add(s, t);
1393 n = tok_ext_size(t);
1394 for(i=0;i<n;i++)
1395 tok_str_add(s, cv->tab[i]);
1398 /* add the current parse token in token string 's' */
1399 static void tok_str_add_tok(TokenString *s)
1401 CValue cval;
1403 /* save line number info */
1404 if (file->line_num != s->last_line_num) {
1405 s->last_line_num = file->line_num;
1406 cval.i = s->last_line_num;
1407 tok_str_add2(s, TOK_LINENUM, &cval);
1409 tok_str_add2(s, tok, &tokc);
1412 /* get a token from an integer array and increment pointer accordingly */
1413 static int tok_get(int **tok_str, CValue *cv)
1415 int *p, t, n, i;
1417 p = *tok_str;
1418 t = *p++;
1419 n = tok_ext_size(t);
1420 for(i=0;i<n;i++)
1421 cv->tab[i] = *p++;
1422 *tok_str = p;
1423 return t;
1426 /* eval an expression for #if/#elif */
1427 int expr_preprocess(void)
1429 int c, t;
1430 TokenString str;
1432 tok_str_new(&str);
1433 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1434 next(); /* do macro subst */
1435 if (tok == TOK_DEFINED) {
1436 next_nomacro();
1437 t = tok;
1438 if (t == '(')
1439 next_nomacro();
1440 c = sym_find1(&define_stack, tok) != 0;
1441 if (t == '(')
1442 next_nomacro();
1443 tok = TOK_CINT;
1444 tokc.i = c;
1445 } else if (tok >= TOK_IDENT) {
1446 /* if undefined macro */
1447 tok = TOK_CINT;
1448 tokc.i = 0;
1450 tok_str_add_tok(&str);
1452 tok_str_add(&str, -1); /* simulate end of file */
1453 tok_str_add(&str, 0);
1454 /* now evaluate C constant expression */
1455 macro_ptr = str.str;
1456 next();
1457 c = expr_const();
1458 macro_ptr = NULL;
1459 free(str.str);
1460 return c != 0;
1463 #if defined(DEBUG) || defined(PP_DEBUG)
1464 void tok_print(int *str)
1466 int t;
1467 CValue cval;
1469 while (1) {
1470 t = tok_get(&str, &cval);
1471 if (!t)
1472 break;
1473 printf(" %s", get_tok_str(t, &cval));
1475 printf("\n");
1477 #endif
1479 /* parse after #define */
1480 void parse_define(void)
1482 Sym *s, *first, **ps;
1483 int v, t, varg, is_vaargs;
1484 TokenString str;
1486 v = tok;
1487 /* XXX: should check if same macro (ANSI) */
1488 first = NULL;
1489 t = MACRO_OBJ;
1490 /* '(' must be just after macro definition for MACRO_FUNC */
1491 if (ch == '(') {
1492 next_nomacro();
1493 next_nomacro();
1494 ps = &first;
1495 while (tok != ')') {
1496 varg = tok;
1497 next_nomacro();
1498 is_vaargs = 0;
1499 if (varg == TOK_DOTS) {
1500 varg = TOK___VA_ARGS__;
1501 is_vaargs = 1;
1502 } else if (tok == TOK_DOTS && gnu_ext) {
1503 is_vaargs = 1;
1504 next_nomacro();
1506 if (varg < TOK_IDENT)
1507 error("badly punctuated parameter list");
1508 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1509 *ps = s;
1510 ps = &s->next;
1511 if (tok != ',')
1512 break;
1513 next_nomacro();
1515 t = MACRO_FUNC;
1517 tok_str_new(&str);
1518 while (1) {
1519 skip_spaces();
1520 if (ch == '\n' || ch == -1)
1521 break;
1522 next_nomacro();
1523 tok_str_add2(&str, tok, &tokc);
1525 tok_str_add(&str, 0);
1526 #ifdef PP_DEBUG
1527 printf("define %s %d: ", get_tok_str(v, NULL), t);
1528 tok_print(str.str);
1529 #endif
1530 s = sym_push1(&define_stack, v, t, (int)str.str);
1531 s->next = first;
1534 void preprocess(void)
1536 int size, i, c;
1537 char buf[1024], *q, *p;
1538 char buf1[1024];
1539 BufferedFile *f;
1540 Sym *s;
1542 return_linefeed = 1; /* linefeed will be returned as a token */
1543 cinp();
1544 next_nomacro();
1545 redo:
1546 if (tok == TOK_DEFINE) {
1547 next_nomacro();
1548 parse_define();
1549 } else if (tok == TOK_UNDEF) {
1550 next_nomacro();
1551 s = sym_find1(&define_stack, tok);
1552 /* undefine symbol by putting an invalid name */
1553 if (s)
1554 sym_undef(&define_stack, s);
1555 } else if (tok == TOK_INCLUDE) {
1556 skip_spaces();
1557 if (ch == '<') {
1558 c = '>';
1559 goto read_name;
1560 } else if (ch == '\"') {
1561 c = ch;
1562 read_name:
1563 minp();
1564 q = buf;
1565 while (ch != c && ch != '\n' && ch != -1) {
1566 if ((q - buf) < sizeof(buf) - 1)
1567 *q++ = ch;
1568 minp();
1570 *q = '\0';
1571 } else {
1572 next();
1573 if (tok != TOK_STR)
1574 error("#include syntax error");
1575 pstrcpy(buf, sizeof(buf), get_tok_str(tok, &tokc));
1576 c = '\"';
1578 /* eat all spaces and comments after include */
1579 /* XXX: slightly incorrect */
1580 while (ch1 != '\n' && ch1 != -1)
1581 inp();
1583 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1584 error("memory full");
1585 if (c == '\"') {
1586 /* first search in current dir if "header.h" */
1587 size = 0;
1588 p = strrchr(file->filename, '/');
1589 if (p)
1590 size = p + 1 - file->filename;
1591 if (size > sizeof(buf1) - 1)
1592 size = sizeof(buf1) - 1;
1593 memcpy(buf1, file->filename, size);
1594 buf1[size] = '\0';
1595 pstrcat(buf1, sizeof(buf1), buf);
1596 f = tcc_open(buf1);
1597 if (f)
1598 goto found;
1600 /* now search in standard include path */
1601 for(i=nb_include_paths - 1;i>=0;i--) {
1602 strcpy(buf1, include_paths[i]);
1603 strcat(buf1, "/");
1604 strcat(buf1, buf);
1605 f = tcc_open(buf1);
1606 if (f)
1607 goto found;
1609 error("include file '%s' not found", buf);
1610 f = NULL;
1611 found:
1612 /* push current file in stack */
1613 /* XXX: fix current line init */
1614 *include_stack_ptr++ = file;
1615 file = f;
1616 /* add include file debug info */
1617 if (do_debug) {
1618 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1620 ch = '\n';
1621 goto the_end;
1622 } else if (tok == TOK_IFNDEF) {
1623 c = 1;
1624 goto do_ifdef;
1625 } else if (tok == TOK_IF) {
1626 c = expr_preprocess();
1627 goto do_if;
1628 } else if (tok == TOK_IFDEF) {
1629 c = 0;
1630 do_ifdef:
1631 next_nomacro();
1632 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1633 do_if:
1634 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1635 error("memory full");
1636 *ifdef_stack_ptr++ = c;
1637 goto test_skip;
1638 } else if (tok == TOK_ELSE) {
1639 if (ifdef_stack_ptr == ifdef_stack)
1640 error("#else without matching #if");
1641 if (ifdef_stack_ptr[-1] & 2)
1642 error("#else after #else");
1643 c = (ifdef_stack_ptr[-1] ^= 3);
1644 goto test_skip;
1645 } else if (tok == TOK_ELIF) {
1646 if (ifdef_stack_ptr == ifdef_stack)
1647 error("#elif without matching #if");
1648 c = ifdef_stack_ptr[-1];
1649 if (c > 1)
1650 error("#elif after #else");
1651 /* last #if/#elif expression was true: we skip */
1652 if (c == 1)
1653 goto skip;
1654 c = expr_preprocess();
1655 ifdef_stack_ptr[-1] = c;
1656 test_skip:
1657 if (!(c & 1)) {
1658 skip:
1659 preprocess_skip();
1660 goto redo;
1662 } else if (tok == TOK_ENDIF) {
1663 if (ifdef_stack_ptr == ifdef_stack)
1664 error("#endif without matching #if");
1665 ifdef_stack_ptr--;
1666 } else if (tok == TOK_LINE) {
1667 next();
1668 if (tok != TOK_CINT)
1669 error("#line");
1670 file->line_num = tokc.i;
1671 skip_spaces();
1672 if (ch != '\n') {
1673 next();
1674 if (tok != TOK_STR)
1675 error("#line");
1676 pstrcpy(file->filename, sizeof(file->filename),
1677 get_tok_str(tok, &tokc));
1679 } else if (tok == TOK_ERROR) {
1680 error("#error");
1682 /* ignore other preprocess commands or #! for C scripts */
1683 while (tok != TOK_LINEFEED && tok != TOK_EOF)
1684 next_nomacro();
1685 the_end:
1686 return_linefeed = 0;
1689 /* read a number in base b */
1690 static int getn(int b)
1692 int n, t;
1693 n = 0;
1694 while (1) {
1695 if (ch >= 'a' && ch <= 'f')
1696 t = ch - 'a' + 10;
1697 else if (ch >= 'A' && ch <= 'F')
1698 t = ch - 'A' + 10;
1699 else if (isnum(ch))
1700 t = ch - '0';
1701 else
1702 break;
1703 if (t < 0 || t >= b)
1704 break;
1705 n = n * b + t;
1706 cinp();
1708 return n;
1711 /* read a character for string or char constant and eval escape codes */
1712 static int getq(void)
1714 int c;
1716 c = ch;
1717 minp();
1718 if (c == '\\') {
1719 if (isnum(ch)) {
1720 /* at most three octal digits */
1721 c = ch - '0';
1722 minp();
1723 if (isnum(ch)) {
1724 c = c * 8 + ch - '0';
1725 minp();
1726 if (isnum(ch)) {
1727 c = c * 8 + ch - '0';
1728 minp();
1731 return c;
1732 } else if (ch == 'x') {
1733 minp();
1734 return getn(16);
1735 } else {
1736 if (ch == 'a')
1737 c = '\a';
1738 else if (ch == 'b')
1739 c = '\b';
1740 else if (ch == 'f')
1741 c = '\f';
1742 else if (ch == 'n')
1743 c = '\n';
1744 else if (ch == 'r')
1745 c = '\r';
1746 else if (ch == 't')
1747 c = '\t';
1748 else if (ch == 'v')
1749 c = '\v';
1750 else if (ch == 'e' && gnu_ext)
1751 c = 27;
1752 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1753 c = ch;
1754 else
1755 error("invalid escaped char");
1756 minp();
1759 return c;
1762 /* we use 64 bit numbers */
1763 #define BN_SIZE 2
1765 /* bn = (bn << shift) | or_val */
1766 void bn_lshift(unsigned int *bn, int shift, int or_val)
1768 int i;
1769 unsigned int v;
1770 for(i=0;i<BN_SIZE;i++) {
1771 v = bn[i];
1772 bn[i] = (v << shift) | or_val;
1773 or_val = v >> (32 - shift);
1777 void bn_zero(unsigned int *bn)
1779 int i;
1780 for(i=0;i<BN_SIZE;i++) {
1781 bn[i] = 0;
1785 void parse_number(void)
1787 int b, t, shift, frac_bits, s, exp_val;
1788 char *q;
1789 unsigned int bn[BN_SIZE];
1790 double d;
1792 /* number */
1793 q = token_buf;
1794 t = ch;
1795 cinp();
1796 *q++ = t;
1797 b = 10;
1798 if (t == '.') {
1799 /* special dot handling */
1800 if (ch >= '0' && ch <= '9') {
1801 goto float_frac_parse;
1802 } else if (ch == '.') {
1803 cinp();
1804 if (ch != '.')
1805 expect("'.'");
1806 cinp();
1807 tok = TOK_DOTS;
1808 } else {
1809 /* dots */
1810 tok = t;
1812 return;
1813 } else if (t == '0') {
1814 if (ch == 'x' || ch == 'X') {
1815 q--;
1816 cinp();
1817 b = 16;
1818 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1819 q--;
1820 cinp();
1821 b = 2;
1824 /* parse all digits. cannot check octal numbers at this stage
1825 because of floating point constants */
1826 while (1) {
1827 if (ch >= 'a' && ch <= 'f')
1828 t = ch - 'a' + 10;
1829 else if (ch >= 'A' && ch <= 'F')
1830 t = ch - 'A' + 10;
1831 else if (isnum(ch))
1832 t = ch - '0';
1833 else
1834 break;
1835 if (t >= b)
1836 break;
1837 if (q >= token_buf + STRING_MAX_SIZE) {
1838 num_too_long:
1839 error("number too long");
1841 *q++ = ch;
1842 cinp();
1844 if (ch == '.' ||
1845 ((ch == 'e' || ch == 'E') && b == 10) ||
1846 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1847 if (b != 10) {
1848 /* NOTE: strtox should support that for hexa numbers, but
1849 non ISOC99 libcs do not support it, so we prefer to do
1850 it by hand */
1851 /* hexadecimal or binary floats */
1852 /* XXX: handle overflows */
1853 *q = '\0';
1854 if (b == 16)
1855 shift = 4;
1856 else
1857 shift = 2;
1858 bn_zero(bn);
1859 q = token_buf;
1860 while (1) {
1861 t = *q++;
1862 if (t == '\0') {
1863 break;
1864 } else if (t >= 'a') {
1865 t = t - 'a' + 10;
1866 } else if (t >= 'A') {
1867 t = t - 'A' + 10;
1868 } else {
1869 t = t - '0';
1871 bn_lshift(bn, shift, t);
1873 frac_bits = 0;
1874 if (ch == '.') {
1875 cinp();
1876 while (1) {
1877 t = ch;
1878 if (t >= 'a' && t <= 'f') {
1879 t = t - 'a' + 10;
1880 } else if (t >= 'A' && t <= 'F') {
1881 t = t - 'A' + 10;
1882 } else if (t >= '0' && t <= '9') {
1883 t = t - '0';
1884 } else {
1885 break;
1887 if (t >= b)
1888 error("invalid digit");
1889 bn_lshift(bn, shift, t);
1890 frac_bits += shift;
1891 cinp();
1894 if (ch != 'p' && ch != 'P')
1895 error("exponent expected");
1896 cinp();
1897 s = 1;
1898 exp_val = 0;
1899 if (ch == '+') {
1900 cinp();
1901 } else if (ch == '-') {
1902 s = -1;
1903 cinp();
1905 if (ch < '0' || ch > '9')
1906 error("exponent digits expected");
1907 while (ch >= '0' && ch <= '9') {
1908 exp_val = exp_val * 10 + ch - '0';
1909 cinp();
1911 exp_val = exp_val * s;
1913 /* now we can generate the number */
1914 /* XXX: should patch directly float number */
1915 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1916 d = ldexp(d, exp_val - frac_bits);
1917 t = toup(ch);
1918 if (t == 'F') {
1919 cinp();
1920 tok = TOK_CFLOAT;
1921 /* float : should handle overflow */
1922 tokc.f = (float)d;
1923 } else if (t == 'L') {
1924 cinp();
1925 tok = TOK_CLDOUBLE;
1926 /* XXX: not large enough */
1927 tokc.ld = (long double)d;
1928 } else {
1929 tok = TOK_CDOUBLE;
1930 tokc.d = d;
1932 } else {
1933 /* decimal floats */
1934 if (ch == '.') {
1935 if (q >= token_buf + STRING_MAX_SIZE)
1936 goto num_too_long;
1937 *q++ = ch;
1938 cinp();
1939 float_frac_parse:
1940 while (ch >= '0' && ch <= '9') {
1941 if (q >= token_buf + STRING_MAX_SIZE)
1942 goto num_too_long;
1943 *q++ = ch;
1944 cinp();
1947 if (ch == 'e' || ch == 'E') {
1948 if (q >= token_buf + STRING_MAX_SIZE)
1949 goto num_too_long;
1950 *q++ = ch;
1951 cinp();
1952 if (ch == '-' || ch == '+') {
1953 if (q >= token_buf + STRING_MAX_SIZE)
1954 goto num_too_long;
1955 *q++ = ch;
1956 cinp();
1958 if (ch < '0' || ch > '9')
1959 error("exponent digits expected");
1960 while (ch >= '0' && ch <= '9') {
1961 if (q >= token_buf + STRING_MAX_SIZE)
1962 goto num_too_long;
1963 *q++ = ch;
1964 cinp();
1967 *q = '\0';
1968 t = toup(ch);
1969 errno = 0;
1970 if (t == 'F') {
1971 cinp();
1972 tok = TOK_CFLOAT;
1973 tokc.f = strtof(token_buf, NULL);
1974 } else if (t == 'L') {
1975 cinp();
1976 tok = TOK_CLDOUBLE;
1977 tokc.ld = strtold(token_buf, NULL);
1978 } else {
1979 tok = TOK_CDOUBLE;
1980 tokc.d = strtod(token_buf, NULL);
1983 } else {
1984 unsigned long long n, n1;
1985 int lcount;
1987 /* integer number */
1988 *q = '\0';
1989 q = token_buf;
1990 if (b == 10 && *q == '0') {
1991 b = 8;
1992 q++;
1994 n = 0;
1995 while(1) {
1996 t = *q++;
1997 /* no need for checks except for base 10 / 8 errors */
1998 if (t == '\0') {
1999 break;
2000 } else if (t >= 'a') {
2001 t = t - 'a' + 10;
2002 } else if (t >= 'A') {
2003 t = t - 'A' + 10;
2004 } else {
2005 t = t - '0';
2006 if (t >= b)
2007 error("invalid digit");
2009 n1 = n;
2010 n = n * b + t;
2011 /* detect overflow */
2012 if (n < n1)
2013 error("integer constant overflow");
2016 /* XXX: not exactly ANSI compliant */
2017 if ((n & 0xffffffff00000000LL) != 0) {
2018 if ((n >> 63) != 0)
2019 tok = TOK_CULLONG;
2020 else
2021 tok = TOK_CLLONG;
2022 } else if (n > 0x7fffffff) {
2023 tok = TOK_CUINT;
2024 } else {
2025 tok = TOK_CINT;
2027 lcount = 0;
2028 for(;;) {
2029 t = toup(ch);
2030 if (t == 'L') {
2031 if (lcount >= 2)
2032 error("three 'l' in integer constant");
2033 lcount++;
2034 if (lcount == 2) {
2035 if (tok == TOK_CINT)
2036 tok = TOK_CLLONG;
2037 else if (tok == TOK_CUINT)
2038 tok = TOK_CULLONG;
2040 cinp();
2041 } else if (t == 'U') {
2042 if (tok == TOK_CINT)
2043 tok = TOK_CUINT;
2044 else if (tok == TOK_CLLONG)
2045 tok = TOK_CULLONG;
2046 cinp();
2047 } else {
2048 break;
2051 if (tok == TOK_CINT || tok == TOK_CUINT)
2052 tokc.ui = n;
2053 else
2054 tokc.ull = n;
2059 /* return next token without macro substitution */
2060 void next_nomacro1(void)
2062 int b;
2063 char *q;
2064 TokenSym *ts;
2066 /* skip spaces */
2067 while(1) {
2068 while (ch == '\n') {
2069 /* during preprocessor parsing, '\n' is a token */
2070 if (return_linefeed) {
2071 tok = TOK_LINEFEED;
2072 return;
2074 cinp();
2075 while (ch == ' ' || ch == '\t')
2076 cinp();
2077 if (ch == '#') {
2078 /* preprocessor command if # at start of line after
2079 spaces */
2080 preprocess();
2083 if (ch != ' ' && ch != '\t' && ch != '\f')
2084 break;
2085 cinp();
2087 if (isid(ch)) {
2088 q = token_buf;
2089 *q++ = ch;
2090 cinp();
2091 if (q[-1] == 'L') {
2092 if (ch == '\'') {
2093 tok = TOK_LCHAR;
2094 goto char_const;
2096 if (ch == '\"') {
2097 tok = TOK_LSTR;
2098 goto str_const;
2101 while (isid(ch) || isnum(ch)) {
2102 if (q >= token_buf + STRING_MAX_SIZE)
2103 error("ident too long");
2104 *q++ = ch;
2105 cinp();
2107 *q = '\0';
2108 ts = tok_alloc(token_buf, q - token_buf);
2109 tok = ts->tok;
2110 } else if (isnum(ch) || ch == '.') {
2111 parse_number();
2112 } else if (ch == '\'') {
2113 tok = TOK_CCHAR;
2114 char_const:
2115 minp();
2116 b = getq();
2117 /* this cast is needed if >= 128 */
2118 if (tok == TOK_CCHAR)
2119 b = (char)b;
2120 tokc.i = b;
2121 if (ch != '\'')
2122 expect("\'");
2123 minp();
2124 } else if (ch == '\"') {
2125 tok = TOK_STR;
2126 str_const:
2127 minp();
2128 q = token_buf;
2129 while (ch != '\"') {
2130 b = getq();
2131 if (ch == -1)
2132 error("unterminated string");
2133 if (q >= token_buf + STRING_MAX_SIZE)
2134 error("string too long");
2135 *q++ = b;
2137 *q = '\0';
2138 tokc.ts = tok_alloc(token_buf, q - token_buf);
2139 minp();
2140 } else {
2141 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2142 /* two chars */
2143 tok = ch;
2144 cinp();
2145 while (*q) {
2146 if (*q == tok && q[1] == ch) {
2147 cinp();
2148 tok = q[2] & 0xff;
2149 /* three chars tests */
2150 if (tok == TOK_SHL || tok == TOK_SAR) {
2151 if (ch == '=') {
2152 tok = tok | 0x80;
2153 cinp();
2155 } else if (tok == TOK_DOTS) {
2156 if (ch != '.')
2157 error("parse error");
2158 cinp();
2160 return;
2162 q = q + 3;
2164 /* single char substitutions */
2165 if (tok == '<')
2166 tok = TOK_LT;
2167 else if (tok == '>')
2168 tok = TOK_GT;
2172 /* return next token without macro substitution. Can read input from
2173 macro_ptr buffer */
2174 void next_nomacro()
2176 if (macro_ptr) {
2177 redo:
2178 tok = *macro_ptr;
2179 if (tok) {
2180 tok = tok_get(&macro_ptr, &tokc);
2181 if (tok == TOK_LINENUM) {
2182 file->line_num = tokc.i;
2183 goto redo;
2186 } else {
2187 next_nomacro1();
2191 /* substitute args in macro_str and return allocated string */
2192 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2194 int *st, last_tok, t, notfirst;
2195 Sym *s;
2196 TokenSym *ts;
2197 CValue cval;
2198 TokenString str;
2200 tok_str_new(&str);
2201 last_tok = 0;
2202 while(1) {
2203 t = tok_get(&macro_str, &cval);
2204 if (!t)
2205 break;
2206 if (t == '#') {
2207 /* stringize */
2208 t = tok_get(&macro_str, &cval);
2209 if (!t)
2210 break;
2211 s = sym_find2(args, t);
2212 if (s) {
2213 token_buf[0] = '\0';
2214 st = (int *)s->c;
2215 notfirst = 0;
2216 while (*st) {
2217 if (notfirst)
2218 pstrcat(token_buf, sizeof(token_buf), " ");
2219 t = tok_get(&st, &cval);
2220 pstrcat(token_buf, sizeof(token_buf), get_tok_str(t, &cval));
2221 notfirst = 1;
2223 #ifdef PP_DEBUG
2224 printf("stringize: %s\n", token_buf);
2225 #endif
2226 /* add string */
2227 ts = tok_alloc(token_buf, 0);
2228 cval.ts = ts;
2229 tok_str_add2(&str, TOK_STR, &cval);
2230 } else {
2231 tok_str_add2(&str, t, &cval);
2233 } else if (t >= TOK_IDENT) {
2234 s = sym_find2(args, t);
2235 if (s) {
2236 st = (int *)s->c;
2237 /* if '##' is present before or after, no arg substitution */
2238 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2239 /* special case for var arg macros : ## eats the
2240 ',' if empty VA_ARGS riable. */
2241 /* XXX: test of the ',' is not 100%
2242 reliable. should fix it to avoid security
2243 problems */
2244 if (gnu_ext && s->t && *st == 0 &&
2245 last_tok == TOK_TWOSHARPS &&
2246 str.len >= 2&& str.str[str.len - 2] == ',') {
2247 /* suppress ',' '##' */
2248 str.len -= 2;
2249 } else {
2250 while (*st)
2251 tok_str_add(&str, *st++);
2253 } else {
2254 macro_subst(&str, nested_list, st);
2256 } else {
2257 tok_str_add(&str, t);
2259 } else {
2260 tok_str_add2(&str, t, &cval);
2262 last_tok = t;
2264 tok_str_add(&str, 0);
2265 return str.str;
2268 /* handle the '##' operator */
2269 int *macro_twosharps(int *macro_str)
2271 TokenSym *ts;
2272 int *macro_ptr1;
2273 int t;
2274 char *p;
2275 CValue cval;
2276 TokenString macro_str1;
2278 tok_str_new(&macro_str1);
2279 tok = 0;
2280 while (1) {
2281 next_nomacro();
2282 if (tok == 0)
2283 break;
2284 while (*macro_ptr == TOK_TWOSHARPS) {
2285 macro_ptr++;
2286 macro_ptr1 = macro_ptr;
2287 t = *macro_ptr;
2288 if (t) {
2289 t = tok_get(&macro_ptr, &cval);
2290 /* XXX: we handle only most common cases:
2291 ident + ident or ident + number */
2292 if (tok >= TOK_IDENT &&
2293 (t >= TOK_IDENT || t == TOK_CINT)) {
2294 p = get_tok_str(tok, &tokc);
2295 pstrcpy(token_buf, sizeof(token_buf), p);
2296 p = get_tok_str(t, &cval);
2297 pstrcat(token_buf, sizeof(token_buf), p);
2298 ts = tok_alloc(token_buf, 0);
2299 tok = ts->tok; /* modify current token */
2300 } else {
2301 /* cannot merge tokens: skip '##' */
2302 macro_ptr = macro_ptr1;
2303 break;
2307 tok_str_add2(&macro_str1, tok, &tokc);
2309 tok_str_add(&macro_str1, 0);
2310 return macro_str1.str;
2313 /* do macro substitution of macro_str and add result to
2314 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2315 substituted. 'nested_list' is the list of all macros we got inside
2316 to avoid recursing. */
2317 void macro_subst(TokenString *tok_str,
2318 Sym **nested_list, int *macro_str)
2320 Sym *s, *args, *sa, *sa1;
2321 int parlevel, *mstr, t, *saved_macro_ptr;
2322 int mstr_allocated, *macro_str1;
2323 CValue cval;
2324 TokenString str;
2326 saved_macro_ptr = macro_ptr;
2327 macro_ptr = macro_str;
2328 macro_str1 = NULL;
2329 if (macro_str) {
2330 /* first scan for '##' operator handling */
2331 macro_str1 = macro_twosharps(macro_str);
2332 macro_ptr = macro_str1;
2335 while (1) {
2336 next_nomacro();
2337 if (tok == 0)
2338 break;
2339 /* special macros */
2340 if (tok == TOK___LINE__) {
2341 cval.i = file->line_num;
2342 tok_str_add2(tok_str, TOK_CINT, &cval);
2343 } else if (tok == TOK___FILE__) {
2344 cval.ts = tok_alloc(file->filename, 0);
2345 tok_str_add2(tok_str, TOK_STR, &cval);
2346 } else if (tok == TOK___DATE__) {
2347 cval.ts = tok_alloc("Jan 1 1970", 0);
2348 tok_str_add2(tok_str, TOK_STR, &cval);
2349 } else if (tok == TOK___TIME__) {
2350 cval.ts = tok_alloc("00:00:00", 0);
2351 tok_str_add2(tok_str, TOK_STR, &cval);
2352 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
2353 /* if symbol is a macro, prepare substitution */
2354 /* if nested substitution, do nothing */
2355 if (sym_find2(*nested_list, tok))
2356 goto no_subst;
2357 mstr = (int *)s->c;
2358 mstr_allocated = 0;
2359 if (s->t == MACRO_FUNC) {
2360 /* NOTE: we do not use next_nomacro to avoid eating the
2361 next token. XXX: find better solution */
2362 if (macro_ptr) {
2363 t = *macro_ptr;
2364 } else {
2365 while (ch == ' ' || ch == '\t' || ch == '\n')
2366 cinp();
2367 t = ch;
2369 if (t != '(') /* no macro subst */
2370 goto no_subst;
2372 /* argument macro */
2373 next_nomacro();
2374 next_nomacro();
2375 args = NULL;
2376 sa = s->next;
2377 /* NOTE: empty args are allowed, except if no args */
2378 for(;;) {
2379 /* handle '()' case */
2380 if (!args && tok == ')')
2381 break;
2382 if (!sa)
2383 error("macro '%s' used with too many args",
2384 get_tok_str(s->v, 0));
2385 tok_str_new(&str);
2386 parlevel = 0;
2387 /* NOTE: non zero sa->t indicates VA_ARGS */
2388 while ((parlevel > 0 ||
2389 (tok != ')' &&
2390 (tok != ',' || sa->t))) &&
2391 tok != -1) {
2392 if (tok == '(')
2393 parlevel++;
2394 else if (tok == ')')
2395 parlevel--;
2396 tok_str_add2(&str, tok, &tokc);
2397 next_nomacro();
2399 tok_str_add(&str, 0);
2400 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2401 sa = sa->next;
2402 if (tok == ')') {
2403 /* special case for gcc var args: add an empty
2404 var arg argument if it is omitted */
2405 if (sa && sa->t && gnu_ext)
2406 continue;
2407 else
2408 break;
2410 if (tok != ',')
2411 expect(",");
2412 next_nomacro();
2414 if (sa) {
2415 error("macro '%s' used with too few args",
2416 get_tok_str(s->v, 0));
2419 /* now subst each arg */
2420 mstr = macro_arg_subst(nested_list, mstr, args);
2421 /* free memory */
2422 sa = args;
2423 while (sa) {
2424 sa1 = sa->prev;
2425 free((int *)sa->c);
2426 free(sa);
2427 sa = sa1;
2429 mstr_allocated = 1;
2431 sym_push2(nested_list, s->v, 0, 0);
2432 macro_subst(tok_str, nested_list, mstr);
2433 /* pop nested defined symbol */
2434 sa1 = *nested_list;
2435 *nested_list = sa1->prev;
2436 free(sa1);
2437 if (mstr_allocated)
2438 free(mstr);
2439 } else {
2440 no_subst:
2441 /* no need to add if reading input stream */
2442 if (!macro_str)
2443 return;
2444 tok_str_add2(tok_str, tok, &tokc);
2446 /* only replace one macro while parsing input stream */
2447 if (!macro_str)
2448 return;
2450 macro_ptr = saved_macro_ptr;
2451 if (macro_str1)
2452 free(macro_str1);
2455 /* return next token with macro substitution */
2456 void next(void)
2458 Sym *nested_list;
2459 TokenString str;
2461 /* special 'ungettok' case for label parsing */
2462 if (tok1) {
2463 tok = tok1;
2464 tokc = tok1c;
2465 tok1 = 0;
2466 } else {
2467 redo:
2468 if (!macro_ptr) {
2469 /* if not reading from macro substituted string, then try
2470 to substitute */
2471 /* XXX: optimize non macro case */
2472 tok_str_new(&str);
2473 nested_list = NULL;
2474 macro_subst(&str, &nested_list, NULL);
2475 if (str.str) {
2476 tok_str_add(&str, 0);
2477 macro_ptr = str.str;
2478 macro_ptr_allocated = str.str;
2479 goto redo;
2481 if (tok == 0)
2482 goto redo;
2483 } else {
2484 next_nomacro();
2485 if (tok == 0) {
2486 /* end of macro string: free it */
2487 free(macro_ptr_allocated);
2488 macro_ptr = NULL;
2489 goto redo;
2493 #if defined(DEBUG)
2494 printf("token = %s\n", get_tok_str(tok, &tokc));
2495 #endif
2498 void swap(int *p, int *q)
2500 int t;
2501 t = *p;
2502 *p = *q;
2503 *q = t;
2506 void vsetc(int t, int r, CValue *vc)
2508 if (vtop >= vstack + VSTACK_SIZE)
2509 error("memory full");
2510 /* cannot let cpu flags if other instruction are generated */
2511 /* XXX: VT_JMP test too ? */
2512 if ((vtop->r & VT_VALMASK) == VT_CMP)
2513 gv(RC_INT);
2514 vtop++;
2515 vtop->t = t;
2516 vtop->r = r;
2517 vtop->r2 = VT_CONST;
2518 vtop->c = *vc;
2521 /* push integer constant */
2522 void vpushi(int v)
2524 CValue cval;
2525 cval.i = v;
2526 vsetc(VT_INT, VT_CONST, &cval);
2529 /* Return a static symbol pointing to a section */
2530 static Sym *get_sym_ref(int t, Section *sec,
2531 unsigned long offset, unsigned long size)
2533 int v;
2534 Sym *sym;
2536 v = anon_sym++;
2537 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2538 sym->r = VT_CONST | VT_SYM;
2539 put_extern_sym(sym, sec, offset);
2540 return sym;
2543 /* push a reference to a section offset by adding a dummy symbol */
2544 /* XXX: add size */
2545 void vpush_ref(int t, Section *sec, unsigned long offset)
2547 CValue cval;
2549 cval.sym = get_sym_ref(t, sec, offset, 0);
2550 vsetc(t, VT_CONST | VT_SYM, &cval);
2553 /* push a reference to symbol v */
2554 void vpush_sym(int t, int v)
2556 Sym *sym;
2557 CValue cval;
2559 sym = external_sym(v, t, 0);
2560 cval.sym = sym;
2561 vsetc(t, VT_CONST | VT_SYM, &cval);
2564 void vset(int t, int r, int v)
2566 CValue cval;
2568 cval.i = v;
2569 vsetc(t, r, &cval);
2572 void vswap(void)
2574 SValue tmp;
2576 tmp = vtop[0];
2577 vtop[0] = vtop[-1];
2578 vtop[-1] = tmp;
2581 void vpushv(SValue *v)
2583 if (vtop >= vstack + VSTACK_SIZE)
2584 error("memory full");
2585 vtop++;
2586 *vtop = *v;
2589 void vdup(void)
2591 vpushv(vtop);
2594 /* save r to the memory stack, and mark it as being free */
2595 void save_reg(int r)
2597 int l, i, saved, t, size, align;
2598 SValue *p, sv;
2600 /* modify all stack values */
2601 saved = 0;
2602 l = 0;
2603 for(p=vstack;p<=vtop;p++) {
2604 i = p->r & VT_VALMASK;
2605 if ((p->r & VT_VALMASK) == r ||
2606 (p->r2 & VT_VALMASK) == r) {
2607 /* must save value on stack if not already done */
2608 if (!saved) {
2609 /* store register in the stack */
2610 t = p->t;
2611 if ((p->r & VT_LVAL) ||
2612 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
2613 t = VT_INT;
2614 size = type_size(t, &align);
2615 loc = (loc - size) & -align;
2616 sv.t = t;
2617 sv.r = VT_LOCAL | VT_LVAL;
2618 sv.c.ul = loc;
2619 store(r, &sv);
2620 #ifdef TCC_TARGET_I386
2621 /* x86 specific: need to pop fp register ST0 if saved */
2622 if (r == REG_ST0) {
2623 o(0xd9dd); /* fstp %st(1) */
2625 #endif
2626 /* special long long case */
2627 if ((t & VT_BTYPE) == VT_LLONG) {
2628 sv.c.ul += 4;
2629 store(p->r2, &sv);
2631 l = loc;
2632 saved = 1;
2634 /* mark that stack entry as being saved on the stack */
2635 if (p->r & VT_LVAL)
2636 t = VT_LLOCAL;
2637 else
2638 t = VT_LOCAL;
2639 p->r = VT_LVAL | t;
2640 p->r2 = VT_CONST;
2641 p->c.ul = l;
2646 /* find a free register of class 'rc'. If none, save one register */
2647 int get_reg(int rc)
2649 int r;
2650 SValue *p;
2652 /* find a free register */
2653 for(r=0;r<NB_REGS;r++) {
2654 if (reg_classes[r] & rc) {
2655 for(p=vstack;p<=vtop;p++) {
2656 if ((p->r & VT_VALMASK) == r ||
2657 (p->r2 & VT_VALMASK) == r)
2658 goto notfound;
2660 return r;
2662 notfound: ;
2665 /* no register left : free the first one on the stack (VERY
2666 IMPORTANT to start from the bottom to ensure that we don't
2667 spill registers used in gen_opi()) */
2668 for(p=vstack;p<=vtop;p++) {
2669 r = p->r & VT_VALMASK;
2670 if (r < VT_CONST && (reg_classes[r] & rc)) {
2671 save_reg(r);
2672 break;
2675 return r;
2678 /* save registers up to (vtop - n) stack entry */
2679 void save_regs(int n)
2681 int r;
2682 SValue *p, *p1;
2683 p1 = vtop - n;
2684 for(p = vstack;p <= p1; p++) {
2685 r = p->r & VT_VALMASK;
2686 if (r < VT_CONST) {
2687 save_reg(r);
2692 /* move register 's' to 'r', and flush previous value of r to memory
2693 if needed */
2694 void move_reg(int r, int s)
2696 SValue sv;
2698 if (r != s) {
2699 save_reg(r);
2700 sv.t = VT_INT;
2701 sv.r = s;
2702 sv.c.ul = 0;
2703 load(r, &sv);
2707 /* get address of vtop (vtop MUST BE an lvalue) */
2708 void gaddrof(void)
2710 vtop->r &= ~VT_LVAL;
2711 /* tricky: if saved lvalue, then we can go back to lvalue */
2712 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
2713 vtop->r = (vtop->r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
2716 #ifdef CONFIG_TCC_BCHECK
2717 /* generate lvalue bound code */
2718 void gbound(void)
2720 int lval_type;
2722 vtop->r &= ~VT_MUSTBOUND;
2723 /* if lvalue, then use checking code before dereferencing */
2724 if (vtop->r & VT_LVAL) {
2725 /* if not VT_BOUNDED value, then make one */
2726 if (!(vtop->r & VT_BOUNDED)) {
2727 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
2728 gaddrof();
2729 vpushi(0);
2730 gen_bounded_ptr_add();
2731 vtop->r |= lval_type;
2733 /* then check for dereferencing */
2734 gen_bounded_ptr_deref();
2737 #endif
2739 /* store vtop a register belonging to class 'rc'. lvalues are
2740 converted to values. Cannot be used if cannot be converted to
2741 register value (such as structures). */
2742 int gv(int rc)
2744 int r, r2, rc2, bit_pos, bit_size, size, align, i;
2745 unsigned long long ll;
2747 /* NOTE: get_reg can modify vstack[] */
2748 if (vtop->t & VT_BITFIELD) {
2749 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
2750 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2751 /* remove bit field info to avoid loops */
2752 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2753 /* generate shifts */
2754 vpushi(32 - (bit_pos + bit_size));
2755 gen_op(TOK_SHL);
2756 vpushi(32 - bit_size);
2757 /* NOTE: transformed to SHR if unsigned */
2758 gen_op(TOK_SAR);
2759 r = gv(rc);
2760 } else {
2761 if (is_float(vtop->t) &&
2762 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2763 int v;
2764 Sym *sym;
2765 int *ptr;
2767 /* XXX: unify with initializers handling ? */
2768 /* CPUs usually cannot use float constants, so we store them
2769 generically in data segment */
2770 size = type_size(vtop->t, &align);
2771 data_section->data_offset = (data_section->data_offset +
2772 align - 1) & -align;
2773 /* XXX: not portable yet */
2774 ptr = section_ptr(data_section, size);
2775 size = size >> 2;
2776 for(i=0;i<size;i++)
2777 ptr[i] = vtop->c.tab[i];
2779 v = anon_sym++;
2780 sym = sym_push1(&global_stack, v, vtop->t | VT_STATIC, 0);
2781 sym->r = VT_CONST | VT_SYM;
2782 put_extern_sym(sym, data_section, data_section->data_offset);
2784 vtop->r |= VT_LVAL | VT_SYM;
2785 vtop->c.sym = sym;
2786 data_section->data_offset += size << 2;
2788 #ifdef CONFIG_TCC_BCHECK
2789 if (vtop->r & VT_MUSTBOUND)
2790 gbound();
2791 #endif
2793 r = vtop->r & VT_VALMASK;
2794 /* need to reload if:
2795 - constant
2796 - lvalue (need to dereference pointer)
2797 - already a register, but not in the right class */
2798 if (r >= VT_CONST ||
2799 (vtop->r & VT_LVAL) ||
2800 !(reg_classes[r] & rc) ||
2801 ((vtop->t & VT_BTYPE) == VT_LLONG &&
2802 !(reg_classes[vtop->r2] & rc))) {
2803 r = get_reg(rc);
2804 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
2805 /* two register type load : expand to two words
2806 temporarily */
2807 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2808 /* load constant */
2809 ll = vtop->c.ull;
2810 vtop->c.ui = ll; /* first word */
2811 load(r, vtop);
2812 vtop->r = r; /* save register value */
2813 vpushi(ll >> 32); /* second word */
2814 } else if (r >= VT_CONST ||
2815 (vtop->r & VT_LVAL)) {
2816 /* load from memory */
2817 load(r, vtop);
2818 vdup();
2819 vtop[-1].r = r; /* save register value */
2820 /* increment pointer to get second word */
2821 vtop->t = VT_INT;
2822 gaddrof();
2823 vpushi(4);
2824 gen_op('+');
2825 vtop->r |= VT_LVAL;
2826 } else {
2827 /* move registers */
2828 load(r, vtop);
2829 vdup();
2830 vtop[-1].r = r; /* save register value */
2831 vtop->r = vtop[-1].r2;
2833 /* allocate second register */
2834 rc2 = RC_INT;
2835 if (rc == RC_IRET)
2836 rc2 = RC_LRET;
2837 r2 = get_reg(rc2);
2838 load(r2, vtop);
2839 vpop();
2840 /* write second register */
2841 vtop->r2 = r2;
2842 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
2843 int t1, t;
2844 /* lvalue of scalar type : need to use lvalue type
2845 because of possible cast */
2846 t = vtop->t;
2847 t1 = t;
2848 /* compute memory access type */
2849 if (vtop->r & VT_LVAL_BYTE)
2850 t = VT_BYTE;
2851 else if (vtop->r & VT_LVAL_SHORT)
2852 t = VT_SHORT;
2853 if (vtop->r & VT_LVAL_UNSIGNED)
2854 t |= VT_UNSIGNED;
2855 vtop->t = t;
2856 load(r, vtop);
2857 /* restore wanted type */
2858 vtop->t = t1;
2859 } else {
2860 /* one register type load */
2861 load(r, vtop);
2864 vtop->r = r;
2866 return r;
2869 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2870 void gv2(int rc1, int rc2)
2872 /* generate more generic register first */
2873 if (rc1 <= rc2) {
2874 vswap();
2875 gv(rc1);
2876 vswap();
2877 gv(rc2);
2878 /* test if reload is needed for first register */
2879 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2880 vswap();
2881 gv(rc1);
2882 vswap();
2884 } else {
2885 gv(rc2);
2886 vswap();
2887 gv(rc1);
2888 vswap();
2889 /* test if reload is needed for first register */
2890 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2891 gv(rc2);
2896 /* expand long long on stack in two int registers */
2897 void lexpand(void)
2899 int u;
2901 u = vtop->t & VT_UNSIGNED;
2902 gv(RC_INT);
2903 vdup();
2904 vtop[0].r = vtop[-1].r2;
2905 vtop[0].r2 = VT_CONST;
2906 vtop[-1].r2 = VT_CONST;
2907 vtop[0].t = VT_INT | u;
2908 vtop[-1].t = VT_INT | u;
2911 /* build a long long from two ints */
2912 void lbuild(int t)
2914 gv2(RC_INT, RC_INT);
2915 vtop[-1].r2 = vtop[0].r;
2916 vtop[-1].t = t;
2917 vpop();
2920 /* rotate n first stack elements to the bottom */
2921 void vrotb(int n)
2923 int i;
2924 SValue tmp;
2926 tmp = vtop[-n + 1];
2927 for(i=-n+1;i!=0;i++)
2928 vtop[i] = vtop[i+1];
2929 vtop[0] = tmp;
2932 /* pop stack value */
2933 void vpop(void)
2935 int v;
2936 v = vtop->r & VT_VALMASK;
2937 #ifdef TCC_TARGET_I386
2938 /* for x86, we need to pop the FP stack */
2939 if (v == REG_ST0) {
2940 o(0xd9dd); /* fstp %st(1) */
2941 } else
2942 #endif
2943 if (v == VT_JMP || v == VT_JMPI) {
2944 /* need to put correct jump if && or || without test */
2945 gsym(vtop->c.ul);
2947 vtop--;
2950 /* convert stack entry to register and duplicate its value in another
2951 register */
2952 void gv_dup(void)
2954 int rc, t, r, r1;
2955 SValue sv;
2957 t = vtop->t;
2958 if ((t & VT_BTYPE) == VT_LLONG) {
2959 lexpand();
2960 gv_dup();
2961 vswap();
2962 vrotb(3);
2963 gv_dup();
2964 vrotb(4);
2965 /* stack: H L L1 H1 */
2966 lbuild(t);
2967 vrotb(3);
2968 vrotb(3);
2969 vswap();
2970 lbuild(t);
2971 vswap();
2972 } else {
2973 /* duplicate value */
2974 rc = RC_INT;
2975 sv.t = VT_INT;
2976 if (is_float(t)) {
2977 rc = RC_FLOAT;
2978 sv.t = t;
2980 r = gv(rc);
2981 r1 = get_reg(rc);
2982 sv.r = r;
2983 sv.c.ul = 0;
2984 load(r1, &sv); /* move r to r1 */
2985 vdup();
2986 /* duplicates value */
2987 vtop->r = r1;
2991 /* generate CPU independent (unsigned) long long operations */
2992 void gen_opl(int op)
2994 int t, a, b, op1, c, i;
2995 int func;
2996 GFuncContext gf;
2997 SValue tmp;
2999 switch(op) {
3000 case '/':
3001 case TOK_PDIV:
3002 func = TOK___divdi3;
3003 goto gen_func;
3004 case TOK_UDIV:
3005 func = TOK___udivdi3;
3006 goto gen_func;
3007 case '%':
3008 func = TOK___moddi3;
3009 goto gen_func;
3010 case TOK_UMOD:
3011 func = TOK___umoddi3;
3012 gen_func:
3013 /* call generic long long function */
3014 gfunc_start(&gf, FUNC_CDECL);
3015 gfunc_param(&gf);
3016 gfunc_param(&gf);
3017 vpush_sym(func_old_type, func);
3018 gfunc_call(&gf);
3019 vpushi(0);
3020 vtop->r = REG_IRET;
3021 vtop->r2 = REG_LRET;
3022 break;
3023 case '^':
3024 case '&':
3025 case '|':
3026 case '*':
3027 case '+':
3028 case '-':
3029 t = vtop->t;
3030 vswap();
3031 lexpand();
3032 vrotb(3);
3033 lexpand();
3034 /* stack: L1 H1 L2 H2 */
3035 tmp = vtop[0];
3036 vtop[0] = vtop[-3];
3037 vtop[-3] = tmp;
3038 tmp = vtop[-2];
3039 vtop[-2] = vtop[-3];
3040 vtop[-3] = tmp;
3041 vswap();
3042 /* stack: H1 H2 L1 L2 */
3043 if (op == '*') {
3044 vpushv(vtop - 1);
3045 vpushv(vtop - 1);
3046 gen_op(TOK_UMULL);
3047 lexpand();
3048 /* stack: H1 H2 L1 L2 ML MH */
3049 for(i=0;i<4;i++)
3050 vrotb(6);
3051 /* stack: ML MH H1 H2 L1 L2 */
3052 tmp = vtop[0];
3053 vtop[0] = vtop[-2];
3054 vtop[-2] = tmp;
3055 /* stack: ML MH H1 L2 H2 L1 */
3056 gen_op('*');
3057 vrotb(3);
3058 vrotb(3);
3059 gen_op('*');
3060 /* stack: ML MH M1 M2 */
3061 gen_op('+');
3062 gen_op('+');
3063 } else if (op == '+' || op == '-') {
3064 /* XXX: add non carry method too (for MIPS or alpha) */
3065 if (op == '+')
3066 op1 = TOK_ADDC1;
3067 else
3068 op1 = TOK_SUBC1;
3069 gen_op(op1);
3070 /* stack: H1 H2 (L1 op L2) */
3071 vrotb(3);
3072 vrotb(3);
3073 gen_op(op1 + 1); /* TOK_xxxC2 */
3074 } else {
3075 gen_op(op);
3076 /* stack: H1 H2 (L1 op L2) */
3077 vrotb(3);
3078 vrotb(3);
3079 /* stack: (L1 op L2) H1 H2 */
3080 gen_op(op);
3081 /* stack: (L1 op L2) (H1 op H2) */
3083 /* stack: L H */
3084 lbuild(t);
3085 break;
3086 case TOK_SAR:
3087 case TOK_SHR:
3088 case TOK_SHL:
3089 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3090 t = vtop[-1].t;
3091 vswap();
3092 lexpand();
3093 vrotb(3);
3094 /* stack: L H shift */
3095 c = (int)vtop->c.i;
3096 /* constant: simpler */
3097 /* NOTE: all comments are for SHL. the other cases are
3098 done by swaping words */
3099 vpop();
3100 if (op != TOK_SHL)
3101 vswap();
3102 if (c >= 32) {
3103 /* stack: L H */
3104 vpop();
3105 if (c > 32) {
3106 vpushi(c - 32);
3107 gen_op(op);
3109 if (op != TOK_SAR) {
3110 vpushi(0);
3111 } else {
3112 gv_dup();
3113 vpushi(31);
3114 gen_op(TOK_SAR);
3116 vswap();
3117 } else {
3118 vswap();
3119 gv_dup();
3120 /* stack: H L L */
3121 vpushi(c);
3122 gen_op(op);
3123 vswap();
3124 vpushi(32 - c);
3125 if (op == TOK_SHL)
3126 gen_op(TOK_SHR);
3127 else
3128 gen_op(TOK_SHL);
3129 vrotb(3);
3130 /* stack: L L H */
3131 vpushi(c);
3132 gen_op(op);
3133 gen_op('|');
3135 if (op != TOK_SHL)
3136 vswap();
3137 lbuild(t);
3138 } else {
3139 /* XXX: should provide a faster fallback on x86 ? */
3140 switch(op) {
3141 case TOK_SAR:
3142 func = TOK___sardi3;
3143 goto gen_func;
3144 case TOK_SHR:
3145 func = TOK___shrdi3;
3146 goto gen_func;
3147 case TOK_SHL:
3148 func = TOK___shldi3;
3149 goto gen_func;
3152 break;
3153 default:
3154 /* compare operations */
3155 t = vtop->t;
3156 vswap();
3157 lexpand();
3158 vrotb(3);
3159 lexpand();
3160 /* stack: L1 H1 L2 H2 */
3161 tmp = vtop[-1];
3162 vtop[-1] = vtop[-2];
3163 vtop[-2] = tmp;
3164 /* stack: L1 L2 H1 H2 */
3165 /* compare high */
3166 op1 = op;
3167 /* when values are equal, we need to compare low words. since
3168 the jump is inverted, we invert the test too. */
3169 if (op1 == TOK_LT)
3170 op1 = TOK_LE;
3171 else if (op1 == TOK_GT)
3172 op1 = TOK_GE;
3173 else if (op1 == TOK_ULT)
3174 op1 = TOK_ULE;
3175 else if (op1 == TOK_UGT)
3176 op1 = TOK_UGE;
3177 a = 0;
3178 b = 0;
3179 gen_op(op1);
3180 if (op1 != TOK_NE) {
3181 a = gtst(1, 0);
3183 if (op != TOK_EQ) {
3184 /* generate non equal test */
3185 /* XXX: NOT PORTABLE yet */
3186 if (a == 0) {
3187 b = gtst(0, 0);
3188 } else {
3189 #ifdef TCC_TARGET_I386
3190 b = psym(0x850f, 0);
3191 #else
3192 error("not implemented");
3193 #endif
3196 /* compare low */
3197 gen_op(op);
3198 a = gtst(1, a);
3199 gsym(b);
3200 vset(VT_INT, VT_JMPI, a);
3201 break;
3205 /* handle integer constant optimizations and various machine
3206 independant opt */
3207 void gen_opic(int op)
3209 int fc, c1, c2, n;
3210 SValue *v1, *v2;
3212 v1 = vtop - 1;
3213 v2 = vtop;
3214 /* currently, we cannot do computations with forward symbols */
3215 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3216 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3217 if (c1 && c2) {
3218 fc = v2->c.i;
3219 switch(op) {
3220 case '+': v1->c.i += fc; break;
3221 case '-': v1->c.i -= fc; break;
3222 case '&': v1->c.i &= fc; break;
3223 case '^': v1->c.i ^= fc; break;
3224 case '|': v1->c.i |= fc; break;
3225 case '*': v1->c.i *= fc; break;
3227 case TOK_PDIV:
3228 case '/':
3229 case '%':
3230 case TOK_UDIV:
3231 case TOK_UMOD:
3232 /* if division by zero, generate explicit division */
3233 if (fc == 0) {
3234 if (const_wanted)
3235 error("division by zero in constant");
3236 goto general_case;
3238 switch(op) {
3239 default: v1->c.i /= fc; break;
3240 case '%': v1->c.i %= fc; break;
3241 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3242 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3244 break;
3245 case TOK_SHL: v1->c.i <<= fc; break;
3246 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3247 case TOK_SAR: v1->c.i >>= fc; break;
3248 /* tests */
3249 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3250 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3251 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3252 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3253 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3254 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3255 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3256 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3257 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3258 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3259 /* logical */
3260 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3261 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3262 default:
3263 goto general_case;
3265 vtop--;
3266 } else {
3267 /* if commutative ops, put c2 as constant */
3268 if (c1 && (op == '+' || op == '&' || op == '^' ||
3269 op == '|' || op == '*')) {
3270 vswap();
3271 swap(&c1, &c2);
3273 fc = vtop->c.i;
3274 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3275 op == TOK_PDIV) &&
3276 fc == 1) ||
3277 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3278 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3279 fc == 0) ||
3280 (op == '&' &&
3281 fc == -1))) {
3282 /* nothing to do */
3283 vtop--;
3284 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3285 /* try to use shifts instead of muls or divs */
3286 if (fc > 0 && (fc & (fc - 1)) == 0) {
3287 n = -1;
3288 while (fc) {
3289 fc >>= 1;
3290 n++;
3292 vtop->c.i = n;
3293 if (op == '*')
3294 op = TOK_SHL;
3295 else if (op == TOK_PDIV)
3296 op = TOK_SAR;
3297 else
3298 op = TOK_SHR;
3300 goto general_case;
3301 } else {
3302 general_case:
3303 /* call low level op generator */
3304 gen_opi(op);
3309 /* generate a floating point operation with constant propagation */
3310 void gen_opif(int op)
3312 int c1, c2;
3313 SValue *v1, *v2;
3314 long double f1, f2;
3316 v1 = vtop - 1;
3317 v2 = vtop;
3318 /* currently, we cannot do computations with forward symbols */
3319 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3320 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3321 if (c1 && c2) {
3322 if (v1->t == VT_FLOAT) {
3323 f1 = v1->c.f;
3324 f2 = v2->c.f;
3325 } else if (v1->t == VT_DOUBLE) {
3326 f1 = v1->c.d;
3327 f2 = v2->c.d;
3328 } else {
3329 f1 = v1->c.ld;
3330 f2 = v2->c.ld;
3333 /* NOTE: we only do constant propagation if finite number (not
3334 NaN or infinity) (ANSI spec) */
3335 if (!ieee_finite(f1) || !ieee_finite(f2))
3336 goto general_case;
3338 switch(op) {
3339 case '+': f1 += f2; break;
3340 case '-': f1 -= f2; break;
3341 case '*': f1 *= f2; break;
3342 case '/':
3343 if (f2 == 0.0) {
3344 if (const_wanted)
3345 error("division by zero in constant");
3346 goto general_case;
3348 f1 /= f2;
3349 break;
3350 /* XXX: also handles tests ? */
3351 default:
3352 goto general_case;
3354 /* XXX: overflow test ? */
3355 if (v1->t == VT_FLOAT) {
3356 v1->c.f = f1;
3357 } else if (v1->t == VT_DOUBLE) {
3358 v1->c.d = f1;
3359 } else {
3360 v1->c.ld = f1;
3362 vtop--;
3363 } else {
3364 general_case:
3365 gen_opf(op);
3370 int pointed_size(int t)
3372 return type_size(pointed_type(t), &t);
3375 #if 0
3376 void check_pointer_types(SValue *p1, SValue *p2)
3378 char buf1[256], buf2[256];
3379 int t1, t2;
3380 t1 = p1->t;
3381 t2 = p2->t;
3382 if (!is_compatible_types(t1, t2)) {
3383 type_to_str(buf1, sizeof(buf1), t1, NULL);
3384 type_to_str(buf2, sizeof(buf2), t2, NULL);
3385 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3388 #endif
3390 /* generic gen_op: handles types problems */
3391 void gen_op(int op)
3393 int u, t1, t2, bt1, bt2, t;
3395 t1 = vtop[-1].t;
3396 t2 = vtop[0].t;
3397 bt1 = t1 & VT_BTYPE;
3398 bt2 = t2 & VT_BTYPE;
3400 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3401 /* at least one operand is a pointer */
3402 /* relationnal op: must be both pointers */
3403 if (op >= TOK_ULT && op <= TOK_GT) {
3404 // check_pointer_types(vtop, vtop - 1);
3405 /* pointers are handled are unsigned */
3406 t = VT_INT | VT_UNSIGNED;
3407 goto std_op;
3409 /* if both pointers, then it must be the '-' op */
3410 if ((t1 & VT_BTYPE) == VT_PTR &&
3411 (t2 & VT_BTYPE) == VT_PTR) {
3412 if (op != '-')
3413 error("cannot use pointers here");
3414 // check_pointer_types(vtop - 1, vtop);
3415 /* XXX: check that types are compatible */
3416 u = pointed_size(t1);
3417 gen_opic(op);
3418 /* set to integer type */
3419 vtop->t = VT_INT;
3420 vpushi(u);
3421 gen_op(TOK_PDIV);
3422 } else {
3423 /* exactly one pointer : must be '+' or '-'. */
3424 if (op != '-' && op != '+')
3425 error("cannot use pointers here");
3426 /* Put pointer as first operand */
3427 if ((t2 & VT_BTYPE) == VT_PTR) {
3428 vswap();
3429 swap(&t1, &t2);
3431 /* XXX: cast to int ? (long long case) */
3432 vpushi(pointed_size(vtop[-1].t));
3433 gen_op('*');
3434 #ifdef CONFIG_TCC_BCHECK
3435 /* if evaluating constant expression, no code should be
3436 generated, so no bound check */
3437 if (do_bounds_check && !const_wanted) {
3438 /* if bounded pointers, we generate a special code to
3439 test bounds */
3440 if (op == '-') {
3441 vpushi(0);
3442 vswap();
3443 gen_op('-');
3445 gen_bounded_ptr_add();
3446 } else
3447 #endif
3449 gen_opic(op);
3451 /* put again type if gen_opic() swaped operands */
3452 vtop->t = t1;
3454 } else if (is_float(bt1) || is_float(bt2)) {
3455 /* compute bigger type and do implicit casts */
3456 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3457 t = VT_LDOUBLE;
3458 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3459 t = VT_DOUBLE;
3460 } else {
3461 t = VT_FLOAT;
3463 /* floats can only be used for a few operations */
3464 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3465 (op < TOK_ULT || op > TOK_GT))
3466 error("invalid operands for binary operation");
3467 goto std_op;
3468 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3469 /* cast to biggest op */
3470 t = VT_LLONG;
3471 /* convert to unsigned if it does not fit in a long long */
3472 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3473 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3474 t |= VT_UNSIGNED;
3475 goto std_op;
3476 } else {
3477 /* integer operations */
3478 t = VT_INT;
3479 /* convert to unsigned if it does not fit in an integer */
3480 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3481 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3482 t |= VT_UNSIGNED;
3483 std_op:
3484 /* XXX: currently, some unsigned operations are explicit, so
3485 we modify them here */
3486 if (t & VT_UNSIGNED) {
3487 if (op == TOK_SAR)
3488 op = TOK_SHR;
3489 else if (op == '/')
3490 op = TOK_UDIV;
3491 else if (op == '%')
3492 op = TOK_UMOD;
3493 else if (op == TOK_LT)
3494 op = TOK_ULT;
3495 else if (op == TOK_GT)
3496 op = TOK_UGT;
3497 else if (op == TOK_LE)
3498 op = TOK_ULE;
3499 else if (op == TOK_GE)
3500 op = TOK_UGE;
3502 vswap();
3503 gen_cast(t);
3504 vswap();
3505 /* special case for shifts and long long: we keep the shift as
3506 an integer */
3507 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3508 gen_cast(VT_INT);
3509 else
3510 gen_cast(t);
3511 if (is_float(t))
3512 gen_opif(op);
3513 else if ((t & VT_BTYPE) == VT_LLONG)
3514 gen_opl(op);
3515 else
3516 gen_opic(op);
3517 if (op >= TOK_ULT && op <= TOK_GT) {
3518 /* relationnal op: the result is an int */
3519 vtop->t = VT_INT;
3520 } else {
3521 vtop->t = t;
3526 /* generic itof for unsigned long long case */
3527 void gen_cvt_itof1(int t)
3529 GFuncContext gf;
3531 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3532 (VT_LLONG | VT_UNSIGNED)) {
3534 gfunc_start(&gf, FUNC_CDECL);
3535 gfunc_param(&gf);
3536 if (t == VT_FLOAT)
3537 vpush_sym(func_old_type, TOK___ulltof);
3538 else if (t == VT_DOUBLE)
3539 vpush_sym(func_old_type, TOK___ulltod);
3540 else
3541 vpush_sym(func_old_type, TOK___ulltold);
3542 gfunc_call(&gf);
3543 vpushi(0);
3544 vtop->r = REG_FRET;
3545 } else {
3546 gen_cvt_itof(t);
3550 /* generic ftoi for unsigned long long case */
3551 void gen_cvt_ftoi1(int t)
3553 GFuncContext gf;
3554 int st;
3556 if (t == (VT_LLONG | VT_UNSIGNED)) {
3557 /* not handled natively */
3558 gfunc_start(&gf, FUNC_CDECL);
3559 st = vtop->t & VT_BTYPE;
3560 gfunc_param(&gf);
3561 if (st == VT_FLOAT)
3562 vpush_sym(func_old_type, TOK___fixunssfdi);
3563 else if (st == VT_DOUBLE)
3564 vpush_sym(func_old_type, TOK___fixunsdfdi);
3565 else
3566 vpush_sym(func_old_type, TOK___fixunsxfdi);
3567 gfunc_call(&gf);
3568 vpushi(0);
3569 vtop->r = REG_IRET;
3570 vtop->r2 = REG_LRET;
3571 } else {
3572 gen_cvt_ftoi(t);
3576 /* force char or short cast */
3577 void force_charshort_cast(int t)
3579 int bits, dbt;
3580 dbt = t & VT_BTYPE;
3581 /* XXX: add optimization if lvalue : just change type and offset */
3582 if (dbt == VT_BYTE)
3583 bits = 8;
3584 else
3585 bits = 16;
3586 if (t & VT_UNSIGNED) {
3587 vpushi((1 << bits) - 1);
3588 gen_op('&');
3589 } else {
3590 bits = 32 - bits;
3591 vpushi(bits);
3592 gen_op(TOK_SHL);
3593 vpushi(bits);
3594 gen_op(TOK_SAR);
3598 /* cast 'vtop' to 't' type */
3599 void gen_cast(int t)
3601 int sbt, dbt, sf, df, c;
3603 /* special delayed cast for char/short */
3604 /* XXX: in some cases (multiple cascaded casts), it may still
3605 be incorrect */
3606 if (vtop->r & VT_MUSTCAST) {
3607 vtop->r &= ~VT_MUSTCAST;
3608 force_charshort_cast(vtop->t);
3611 dbt = t & (VT_BTYPE | VT_UNSIGNED);
3612 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
3614 if (sbt != dbt) {
3615 sf = is_float(sbt);
3616 df = is_float(dbt);
3617 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3618 if (sf && df) {
3619 /* convert from fp to fp */
3620 if (c) {
3621 /* constant case: we can do it now */
3622 /* XXX: in ISOC, cannot do it if error in convert */
3623 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
3624 vtop->c.f = (float)vtop->c.d;
3625 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
3626 vtop->c.f = (float)vtop->c.ld;
3627 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
3628 vtop->c.d = (double)vtop->c.f;
3629 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
3630 vtop->c.d = (double)vtop->c.ld;
3631 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
3632 vtop->c.ld = (long double)vtop->c.f;
3633 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
3634 vtop->c.ld = (long double)vtop->c.d;
3635 } else {
3636 /* non constant case: generate code */
3637 gen_cvt_ftof(dbt);
3639 } else if (df) {
3640 /* convert int to fp */
3641 if (c) {
3642 switch(sbt) {
3643 case VT_LLONG | VT_UNSIGNED:
3644 case VT_LLONG:
3645 /* XXX: add const cases for long long */
3646 goto do_itof;
3647 case VT_INT | VT_UNSIGNED:
3648 switch(dbt) {
3649 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
3650 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
3651 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
3653 break;
3654 default:
3655 switch(dbt) {
3656 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
3657 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
3658 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
3660 break;
3662 } else {
3663 do_itof:
3664 gen_cvt_itof1(dbt);
3666 } else if (sf) {
3667 /* convert fp to int */
3668 /* we handle char/short/etc... with generic code */
3669 if (dbt != (VT_INT | VT_UNSIGNED) &&
3670 dbt != (VT_LLONG | VT_UNSIGNED) &&
3671 dbt != VT_LLONG)
3672 dbt = VT_INT;
3673 if (c) {
3674 switch(dbt) {
3675 case VT_LLONG | VT_UNSIGNED:
3676 case VT_LLONG:
3677 /* XXX: add const cases for long long */
3678 goto do_ftoi;
3679 case VT_INT | VT_UNSIGNED:
3680 switch(sbt) {
3681 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
3682 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3683 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3685 break;
3686 default:
3687 /* int case */
3688 switch(sbt) {
3689 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
3690 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
3691 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
3693 break;
3695 } else {
3696 do_ftoi:
3697 gen_cvt_ftoi1(dbt);
3699 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
3700 /* additionnal cast for char/short/bool... */
3701 vtop->t = dbt;
3702 gen_cast(t);
3704 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
3705 if ((sbt & VT_BTYPE) != VT_LLONG) {
3706 /* scalar to long long */
3707 if (c) {
3708 if (sbt == (VT_INT | VT_UNSIGNED))
3709 vtop->c.ll = vtop->c.ui;
3710 else
3711 vtop->c.ll = vtop->c.i;
3712 } else {
3713 /* machine independant conversion */
3714 gv(RC_INT);
3715 /* generate high word */
3716 if (sbt == (VT_INT | VT_UNSIGNED)) {
3717 vpushi(0);
3718 gv(RC_INT);
3719 } else {
3720 gv_dup();
3721 vpushi(31);
3722 gen_op(TOK_SAR);
3724 /* patch second register */
3725 vtop[-1].r2 = vtop->r;
3726 vpop();
3729 } else if (dbt == VT_BOOL) {
3730 /* scalar to bool */
3731 vpushi(0);
3732 gen_op(TOK_NE);
3733 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
3734 (dbt & VT_BTYPE) == VT_SHORT) {
3735 force_charshort_cast(t);
3736 } else if ((dbt & VT_BTYPE) == VT_INT) {
3737 /* scalar to int */
3738 if (sbt == VT_LLONG) {
3739 /* from long long: just take low order word */
3740 lexpand();
3741 vpop();
3743 /* if lvalue and single word type, nothing to do because
3744 the lvalue already contains the real type size (see
3745 VT_LVAL_xxx constants) */
3748 vtop->t = t;
3751 /* return type size. Put alignment at 'a' */
3752 int type_size(int t, int *a)
3754 Sym *s;
3755 int bt;
3757 bt = t & VT_BTYPE;
3758 if (bt == VT_STRUCT) {
3759 /* struct/union */
3760 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3761 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
3762 return s->c;
3763 } else if (bt == VT_PTR) {
3764 if (t & VT_ARRAY) {
3765 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3766 return type_size(s->t, a) * s->c;
3767 } else {
3768 *a = PTR_SIZE;
3769 return PTR_SIZE;
3771 } else if (bt == VT_LDOUBLE) {
3772 *a = LDOUBLE_ALIGN;
3773 return LDOUBLE_SIZE;
3774 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3775 *a = 8;
3776 return 8;
3777 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
3778 *a = 4;
3779 return 4;
3780 } else if (bt == VT_SHORT) {
3781 *a = 2;
3782 return 2;
3783 } else {
3784 /* char, void, function, _Bool */
3785 *a = 1;
3786 return 1;
3790 /* return the pointed type of t */
3791 int pointed_type(int t)
3793 Sym *s;
3794 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3795 return s->t | (t & ~VT_TYPE);
3798 int mk_pointer(int t)
3800 int p;
3801 p = anon_sym++;
3802 sym_push(p, t, 0, -1);
3803 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
3806 int is_compatible_types(int t1, int t2)
3808 Sym *s1, *s2;
3809 int bt1, bt2;
3811 t1 &= VT_TYPE;
3812 t2 &= VT_TYPE;
3813 bt1 = t1 & VT_BTYPE;
3814 bt2 = t2 & VT_BTYPE;
3815 if (bt1 == VT_PTR) {
3816 t1 = pointed_type(t1);
3817 /* if function, then convert implicitely to function pointer */
3818 if (bt2 != VT_FUNC) {
3819 if (bt2 != VT_PTR)
3820 return 0;
3821 t2 = pointed_type(t2);
3823 /* void matches everything */
3824 t1 &= VT_TYPE;
3825 t2 &= VT_TYPE;
3826 if (t1 == VT_VOID || t2 == VT_VOID)
3827 return 1;
3828 return is_compatible_types(t1, t2);
3829 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3830 return (t2 == t1);
3831 } else if (bt1 == VT_FUNC) {
3832 if (bt2 != VT_FUNC)
3833 return 0;
3834 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
3835 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
3836 if (!is_compatible_types(s1->t, s2->t))
3837 return 0;
3838 /* XXX: not complete */
3839 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
3840 return 1;
3841 if (s1->c != s2->c)
3842 return 0;
3843 while (s1 != NULL) {
3844 if (s2 == NULL)
3845 return 0;
3846 if (!is_compatible_types(s1->t, s2->t))
3847 return 0;
3848 s1 = s1->next;
3849 s2 = s2->next;
3851 if (s2)
3852 return 0;
3853 return 1;
3854 } else {
3855 /* XXX: not complete */
3856 return 1;
3860 /* print a type. If 'varstr' is not NULL, then the variable is also
3861 printed in the type */
3862 /* XXX: union */
3863 /* XXX: add array and function pointers */
3864 void type_to_str(char *buf, int buf_size,
3865 int t, const char *varstr)
3867 int bt, v;
3868 Sym *s, *sa;
3869 char buf1[256];
3870 const char *tstr;
3872 t = t & VT_TYPE;
3873 bt = t & VT_BTYPE;
3874 buf[0] = '\0';
3875 if (t & VT_UNSIGNED)
3876 pstrcat(buf, buf_size, "unsigned ");
3877 switch(bt) {
3878 case VT_VOID:
3879 tstr = "void";
3880 goto add_tstr;
3881 case VT_BOOL:
3882 tstr = "_Bool";
3883 goto add_tstr;
3884 case VT_BYTE:
3885 tstr = "char";
3886 goto add_tstr;
3887 case VT_SHORT:
3888 tstr = "short";
3889 goto add_tstr;
3890 case VT_INT:
3891 tstr = "int";
3892 goto add_tstr;
3893 case VT_LONG:
3894 tstr = "long";
3895 goto add_tstr;
3896 case VT_LLONG:
3897 tstr = "long long";
3898 goto add_tstr;
3899 case VT_FLOAT:
3900 tstr = "float";
3901 goto add_tstr;
3902 case VT_DOUBLE:
3903 tstr = "double";
3904 goto add_tstr;
3905 case VT_LDOUBLE:
3906 tstr = "long double";
3907 add_tstr:
3908 pstrcat(buf, buf_size, tstr);
3909 break;
3910 case VT_ENUM:
3911 case VT_STRUCT:
3912 if (bt == VT_STRUCT)
3913 tstr = "struct ";
3914 else
3915 tstr = "enum ";
3916 pstrcat(buf, buf_size, tstr);
3917 v = (unsigned)t >> VT_STRUCT_SHIFT;
3918 if (v >= SYM_FIRST_ANOM)
3919 pstrcat(buf, buf_size, "<anonymous>");
3920 else
3921 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3922 break;
3923 case VT_FUNC:
3924 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3925 type_to_str(buf, buf_size, s->t, varstr);
3926 pstrcat(buf, buf_size, "(");
3927 sa = s->next;
3928 while (sa != NULL) {
3929 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
3930 pstrcat(buf, buf_size, buf1);
3931 sa = sa->next;
3932 if (sa)
3933 pstrcat(buf, buf_size, ", ");
3935 pstrcat(buf, buf_size, ")");
3936 goto no_var;
3937 case VT_PTR:
3938 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3939 pstrcpy(buf1, sizeof(buf1), "*");
3940 if (varstr)
3941 pstrcat(buf1, sizeof(buf1), varstr);
3942 type_to_str(buf, buf_size, s->t, buf1);
3943 goto no_var;
3945 if (varstr) {
3946 pstrcat(buf, buf_size, " ");
3947 pstrcat(buf, buf_size, varstr);
3949 no_var: ;
3952 /* verify type compatibility to store vtop in 'dt' type, and generate
3953 casts if needed. */
3954 void gen_assign_cast(int dt)
3956 int st;
3957 char buf1[256], buf2[256];
3959 st = vtop->t; /* source type */
3960 if ((dt & VT_BTYPE) == VT_PTR) {
3961 /* special cases for pointers */
3962 /* a function is implicitely a function pointer */
3963 if ((st & VT_BTYPE) == VT_FUNC) {
3964 if (!is_compatible_types(pointed_type(dt), st))
3965 goto error;
3966 else
3967 goto type_ok;
3969 /* '0' can also be a pointer */
3970 if ((st & VT_BTYPE) == VT_INT &&
3971 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
3972 vtop->c.i == 0)
3973 goto type_ok;
3975 if (!is_compatible_types(dt, st)) {
3976 error:
3977 type_to_str(buf1, sizeof(buf1), st, NULL);
3978 type_to_str(buf2, sizeof(buf2), dt, NULL);
3979 error("cannot cast '%s' to '%s'", buf1, buf2);
3981 type_ok:
3982 gen_cast(dt);
3985 /* store vtop in lvalue pushed on stack */
3986 void vstore(void)
3988 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
3989 GFuncContext gf;
3991 ft = vtop[-1].t;
3992 sbt = vtop->t & VT_BTYPE;
3993 dbt = ft & VT_BTYPE;
3994 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
3995 (sbt == VT_INT && dbt == VT_SHORT)) {
3996 /* optimize char/short casts */
3997 delayed_cast = VT_MUSTCAST;
3998 vtop->t = ft & VT_TYPE;
3999 } else {
4000 delayed_cast = 0;
4001 gen_assign_cast(ft & VT_TYPE);
4004 if (sbt == VT_STRUCT) {
4005 /* if structure, only generate pointer */
4006 /* structure assignment : generate memcpy */
4007 /* XXX: optimize if small size */
4008 vdup();
4009 gfunc_start(&gf, FUNC_CDECL);
4010 /* type size */
4011 size = type_size(vtop->t, &align);
4012 vpushi(size);
4013 gfunc_param(&gf);
4014 /* source */
4015 vtop->t = VT_INT;
4016 gaddrof();
4017 gfunc_param(&gf);
4018 /* destination */
4019 vswap();
4020 vtop->t = VT_INT;
4021 gaddrof();
4022 gfunc_param(&gf);
4024 save_regs(0);
4025 vpush_sym(func_old_type, TOK_memcpy);
4026 gfunc_call(&gf);
4027 /* leave source on stack */
4028 } else if (ft & VT_BITFIELD) {
4029 /* bitfield store handling */
4030 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4031 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4032 /* remove bit field info to avoid loops */
4033 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4035 /* duplicate destination */
4036 vdup();
4037 vtop[-1] = vtop[-2];
4039 /* mask and shift source */
4040 vpushi((1 << bit_size) - 1);
4041 gen_op('&');
4042 vpushi(bit_pos);
4043 gen_op(TOK_SHL);
4044 /* load destination, mask and or with source */
4045 vswap();
4046 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4047 gen_op('&');
4048 gen_op('|');
4049 /* store result */
4050 vstore();
4051 } else {
4052 #ifdef CONFIG_TCC_BCHECK
4053 /* bound check case */
4054 if (vtop[-1].r & VT_MUSTBOUND) {
4055 vswap();
4056 gbound();
4057 vswap();
4059 #endif
4060 rc = RC_INT;
4061 if (is_float(ft))
4062 rc = RC_FLOAT;
4063 r = gv(rc); /* generate value */
4064 /* if lvalue was saved on stack, must read it */
4065 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4066 SValue sv;
4067 t = get_reg(RC_INT);
4068 sv.t = VT_INT;
4069 sv.r = VT_LOCAL | VT_LVAL;
4070 sv.c.ul = vtop[-1].c.ul;
4071 load(t, &sv);
4072 vtop[-1].r = t | VT_LVAL;
4074 store(r, vtop - 1);
4075 /* two word case handling : store second register at word + 4 */
4076 if ((ft & VT_BTYPE) == VT_LLONG) {
4077 vswap();
4078 /* convert to int to increment easily */
4079 vtop->t = VT_INT;
4080 gaddrof();
4081 vpushi(4);
4082 gen_op('+');
4083 vtop->r |= VT_LVAL;
4084 vswap();
4085 /* XXX: it works because r2 is spilled last ! */
4086 store(vtop->r2, vtop - 1);
4088 vswap();
4089 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4090 vtop->r |= delayed_cast;
4094 /* post defines POST/PRE add. c is the token ++ or -- */
4095 void inc(int post, int c)
4097 test_lvalue();
4098 vdup(); /* save lvalue */
4099 if (post) {
4100 gv_dup(); /* duplicate value */
4101 vrotb(3);
4102 vrotb(3);
4104 /* add constant */
4105 vpushi(c - TOK_MID);
4106 gen_op('+');
4107 vstore(); /* store value */
4108 if (post)
4109 vpop(); /* if post op, return saved value */
4112 /* Parse GNUC __attribute__ extension. Currently, the following
4113 extensions are recognized:
4114 - aligned(n) : set data/function alignment.
4115 - section(x) : generate data/code in this section.
4116 - unused : currently ignored, but may be used someday.
4118 void parse_attribute(AttributeDef *ad)
4120 int t, n;
4122 next();
4123 skip('(');
4124 skip('(');
4125 while (tok != ')') {
4126 if (tok < TOK_IDENT)
4127 expect("attribute name");
4128 t = tok;
4129 next();
4130 switch(t) {
4131 case TOK_SECTION:
4132 case TOK___SECTION__:
4133 skip('(');
4134 if (tok != TOK_STR)
4135 expect("section name");
4136 ad->section = find_section(tokc.ts->str);
4137 next();
4138 skip(')');
4139 break;
4140 case TOK_ALIGNED:
4141 case TOK___ALIGNED__:
4142 skip('(');
4143 n = expr_const();
4144 if (n <= 0 || (n & (n - 1)) != 0)
4145 error("alignment must be a positive power of two");
4146 ad->aligned = n;
4147 skip(')');
4148 break;
4149 case TOK_UNUSED:
4150 case TOK___UNUSED__:
4151 /* currently, no need to handle it because tcc does not
4152 track unused objects */
4153 break;
4154 case TOK_NORETURN:
4155 case TOK___NORETURN__:
4156 /* currently, no need to handle it because tcc does not
4157 track unused objects */
4158 break;
4159 case TOK_CDECL:
4160 case TOK___CDECL:
4161 case TOK___CDECL__:
4162 ad->func_call = FUNC_CDECL;
4163 break;
4164 case TOK_STDCALL:
4165 case TOK___STDCALL:
4166 case TOK___STDCALL__:
4167 ad->func_call = FUNC_STDCALL;
4168 break;
4169 default:
4170 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4171 /* skip parameters */
4172 /* XXX: skip parenthesis too */
4173 if (tok == '(') {
4174 next();
4175 while (tok != ')' && tok != -1)
4176 next();
4177 next();
4179 break;
4181 if (tok != ',')
4182 break;
4183 next();
4185 skip(')');
4186 skip(')');
4189 /* enum/struct/union declaration */
4190 int struct_decl(int u)
4192 int a, t, b, v, size, align, maxalign, c, offset;
4193 int bit_size, bit_pos, bsize, bt, lbit_pos;
4194 Sym *s, *ss, **ps;
4195 AttributeDef ad;
4197 a = tok; /* save decl type */
4198 next();
4199 if (tok != '{') {
4200 v = tok;
4201 next();
4202 /* struct already defined ? return it */
4203 /* XXX: check consistency */
4204 s = sym_find(v | SYM_STRUCT);
4205 if (s) {
4206 if (s->t != a)
4207 error("invalid type");
4208 goto do_decl;
4210 } else {
4211 v = anon_sym++;
4213 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4214 /* put struct/union/enum name in type */
4215 do_decl:
4216 u = u | (v << VT_STRUCT_SHIFT);
4218 if (tok == '{') {
4219 next();
4220 if (s->c)
4221 error("struct/union/enum already defined");
4222 /* cannot be empty */
4223 c = 0;
4224 maxalign = 0;
4225 ps = &s->next;
4226 bit_pos = 0;
4227 offset = 0;
4228 while (1) {
4229 if (a == TOK_ENUM) {
4230 v = tok;
4231 next();
4232 if (tok == '=') {
4233 next();
4234 c = expr_const();
4236 /* enum symbols have static storage */
4237 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4238 if (tok == ',')
4239 next();
4240 c++;
4241 } else {
4242 parse_btype(&b, &ad);
4243 while (1) {
4244 bit_size = -1;
4245 v = 0;
4246 if (tok != ':') {
4247 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4248 if ((t & VT_BTYPE) == VT_FUNC ||
4249 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4250 error("invalid type for '%s'",
4251 get_tok_str(v, NULL));
4252 } else {
4253 t = b;
4255 if (tok == ':') {
4256 next();
4257 bit_size = expr_const();
4258 /* XXX: handle v = 0 case for messages */
4259 if (bit_size < 0)
4260 error("negative width in bit-field '%s'",
4261 get_tok_str(v, NULL));
4262 if (v && bit_size == 0)
4263 error("zero width for bit-field '%s'",
4264 get_tok_str(v, NULL));
4266 size = type_size(t, &align);
4267 lbit_pos = 0;
4268 if (bit_size >= 0) {
4269 bt = t & VT_BTYPE;
4270 if (bt != VT_INT &&
4271 bt != VT_BYTE &&
4272 bt != VT_SHORT)
4273 error("bitfields must have scalar type");
4274 bsize = size * 8;
4275 if (bit_size > bsize) {
4276 error("width of '%s' exceeds its type",
4277 get_tok_str(v, NULL));
4278 } else if (bit_size == bsize) {
4279 /* no need for bit fields */
4280 bit_pos = 0;
4281 } else if (bit_size == 0) {
4282 /* XXX: what to do if only padding in a
4283 structure ? */
4284 /* zero size: means to pad */
4285 if (bit_pos > 0)
4286 bit_pos = bsize;
4287 } else {
4288 /* we do not have enough room ? */
4289 if ((bit_pos + bit_size) > bsize)
4290 bit_pos = 0;
4291 lbit_pos = bit_pos;
4292 /* XXX: handle LSB first */
4293 t |= VT_BITFIELD |
4294 (bit_pos << VT_STRUCT_SHIFT) |
4295 (bit_size << (VT_STRUCT_SHIFT + 6));
4296 bit_pos += bit_size;
4298 } else {
4299 bit_pos = 0;
4301 if (v) {
4302 /* add new memory data only if starting
4303 bit field */
4304 if (lbit_pos == 0) {
4305 if (a == TOK_STRUCT) {
4306 c = (c + align - 1) & -align;
4307 offset = c;
4308 c += size;
4309 } else {
4310 offset = 0;
4311 if (size > c)
4312 c = size;
4314 if (align > maxalign)
4315 maxalign = align;
4317 #if 0
4318 printf("add field %s offset=%d",
4319 get_tok_str(v, NULL), offset);
4320 if (t & VT_BITFIELD) {
4321 printf(" pos=%d size=%d",
4322 (t >> VT_STRUCT_SHIFT) & 0x3f,
4323 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4325 printf("\n");
4326 #endif
4327 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4328 *ps = ss;
4329 ps = &ss->next;
4331 if (tok == ';' || tok == -1)
4332 break;
4333 skip(',');
4335 skip(';');
4337 if (tok == '}')
4338 break;
4340 skip('}');
4341 /* size for struct/union, dummy for enum */
4342 s->c = (c + maxalign - 1) & -maxalign;
4344 return u;
4347 /* return 0 if no type declaration. otherwise, return the basic type
4348 and skip it.
4350 int parse_btype(int *type_ptr, AttributeDef *ad)
4352 int t, u, type_found;
4353 Sym *s;
4355 memset(ad, 0, sizeof(AttributeDef));
4356 type_found = 0;
4357 t = 0;
4358 while(1) {
4359 switch(tok) {
4360 /* basic types */
4361 case TOK_CHAR:
4362 u = VT_BYTE;
4363 basic_type:
4364 next();
4365 basic_type1:
4366 if ((t & VT_BTYPE) != 0)
4367 error("too many basic types");
4368 t |= u;
4369 break;
4370 case TOK_VOID:
4371 u = VT_VOID;
4372 goto basic_type;
4373 case TOK_SHORT:
4374 u = VT_SHORT;
4375 goto basic_type;
4376 case TOK_INT:
4377 next();
4378 break;
4379 case TOK_LONG:
4380 next();
4381 if ((t & VT_BTYPE) == VT_DOUBLE) {
4382 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4383 } else if ((t & VT_BTYPE) == VT_LONG) {
4384 t = (t & ~VT_BTYPE) | VT_LLONG;
4385 } else {
4386 u = VT_LONG;
4387 goto basic_type1;
4389 break;
4390 case TOK_BOOL:
4391 u = VT_BOOL;
4392 goto basic_type;
4393 case TOK_FLOAT:
4394 u = VT_FLOAT;
4395 goto basic_type;
4396 case TOK_DOUBLE:
4397 next();
4398 if ((t & VT_BTYPE) == VT_LONG) {
4399 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4400 } else {
4401 u = VT_DOUBLE;
4402 goto basic_type1;
4404 break;
4405 case TOK_ENUM:
4406 u = struct_decl(VT_ENUM);
4407 goto basic_type1;
4408 case TOK_STRUCT:
4409 case TOK_UNION:
4410 u = struct_decl(VT_STRUCT);
4411 goto basic_type1;
4413 /* type modifiers */
4414 case TOK_CONST:
4415 case TOK_VOLATILE:
4416 case TOK_REGISTER:
4417 case TOK_SIGNED:
4418 case TOK___SIGNED__:
4419 case TOK_AUTO:
4420 case TOK_INLINE:
4421 case TOK___INLINE__:
4422 case TOK_RESTRICT:
4423 next();
4424 break;
4425 case TOK_UNSIGNED:
4426 t |= VT_UNSIGNED;
4427 next();
4428 break;
4430 /* storage */
4431 case TOK_EXTERN:
4432 t |= VT_EXTERN;
4433 next();
4434 break;
4435 case TOK_STATIC:
4436 t |= VT_STATIC;
4437 next();
4438 break;
4439 case TOK_TYPEDEF:
4440 t |= VT_TYPEDEF;
4441 next();
4442 break;
4443 /* GNUC attribute */
4444 case TOK___ATTRIBUTE__:
4445 parse_attribute(ad);
4446 break;
4447 default:
4448 s = sym_find(tok);
4449 if (!s || !(s->t & VT_TYPEDEF))
4450 goto the_end;
4451 t |= (s->t & ~VT_TYPEDEF);
4452 next();
4453 break;
4455 type_found = 1;
4457 the_end:
4458 /* long is never used as type */
4459 if ((t & VT_BTYPE) == VT_LONG)
4460 t = (t & ~VT_BTYPE) | VT_INT;
4461 *type_ptr = t;
4462 return type_found;
4465 int post_type(int t, AttributeDef *ad)
4467 int p, n, pt, l, t1;
4468 Sym **plast, *s, *first;
4469 AttributeDef ad1;
4471 if (tok == '(') {
4472 /* function declaration */
4473 next();
4474 l = 0;
4475 first = NULL;
4476 plast = &first;
4477 while (tok != ')') {
4478 /* read param name and compute offset */
4479 if (l != FUNC_OLD) {
4480 if (!parse_btype(&pt, &ad1)) {
4481 if (l) {
4482 error("invalid type");
4483 } else {
4484 l = FUNC_OLD;
4485 goto old_proto;
4488 l = FUNC_NEW;
4489 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4490 break;
4491 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4492 if ((pt & VT_BTYPE) == VT_VOID)
4493 error("parameter declared as void");
4494 } else {
4495 old_proto:
4496 n = tok;
4497 pt = VT_INT;
4498 next();
4500 /* array must be transformed to pointer according to ANSI C */
4501 pt &= ~VT_ARRAY;
4502 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4503 *plast = s;
4504 plast = &s->next;
4505 if (tok == ',') {
4506 next();
4507 if (l == FUNC_NEW && tok == TOK_DOTS) {
4508 l = FUNC_ELLIPSIS;
4509 next();
4510 break;
4514 /* if no parameters, then old type prototype */
4515 if (l == 0)
4516 l = FUNC_OLD;
4517 skip(')');
4518 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4519 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4520 /* we push a anonymous symbol which will contain the function prototype */
4521 p = anon_sym++;
4522 s = sym_push(p, t, ad->func_call, l);
4523 s->next = first;
4524 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4525 } else if (tok == '[') {
4526 /* array definition */
4527 next();
4528 n = -1;
4529 if (tok != ']') {
4530 n = expr_const();
4531 if (n < 0)
4532 error("invalid array size");
4534 skip(']');
4535 /* parse next post type */
4536 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4537 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4539 /* we push a anonymous symbol which will contain the array
4540 element type */
4541 p = anon_sym++;
4542 sym_push(p, t, 0, n);
4543 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4545 return t;
4548 /* Read a type declaration (except basic type), and return the
4549 type. 'td' is a bitmask indicating which kind of type decl is
4550 expected. 't' should contain the basic type. 'ad' is the attribute
4551 definition of the basic type. It can be modified by type_decl(). */
4552 int type_decl(AttributeDef *ad, int *v, int t, int td)
4554 int u, p;
4555 Sym *s;
4557 while (tok == '*') {
4558 next();
4559 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4560 next();
4561 t = mk_pointer(t);
4564 /* recursive type */
4565 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4566 if (tok == '(') {
4567 next();
4568 /* XXX: this is not correct to modify 'ad' at this point, but
4569 the syntax is not clear */
4570 if (tok == TOK___ATTRIBUTE__)
4571 parse_attribute(ad);
4572 u = type_decl(ad, v, 0, td);
4573 skip(')');
4574 } else {
4575 u = 0;
4576 /* type identifier */
4577 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4578 *v = tok;
4579 next();
4580 } else {
4581 if (!(td & TYPE_ABSTRACT))
4582 expect("identifier");
4583 *v = 0;
4586 /* append t at the end of u */
4587 t = post_type(t, ad);
4588 if (tok == TOK___ATTRIBUTE__)
4589 parse_attribute(ad);
4590 if (!u)
4591 return t;
4592 p = u;
4593 while(1) {
4594 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4595 p = s->t;
4596 if (!p) {
4597 s->t = t;
4598 break;
4601 return u;
4604 /* define a new external reference to a symbol 'v' of type 'u' */
4605 Sym *external_sym(int v, int u, int r)
4607 Sym *s;
4609 s = sym_find(v);
4610 if (!s) {
4611 /* push forward reference */
4612 s = sym_push1(&global_stack,
4613 v, u | VT_EXTERN, 0);
4614 s->r = r | VT_CONST | VT_SYM;
4616 return s;
4619 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4620 static int lvalue_type(int t)
4622 int bt, r;
4623 r = VT_LVAL;
4624 bt = t & VT_BTYPE;
4625 if (bt == VT_BYTE)
4626 r |= VT_LVAL_BYTE;
4627 else if (bt == VT_SHORT)
4628 r |= VT_LVAL_SHORT;
4629 else
4630 return r;
4631 if (t & VT_UNSIGNED)
4632 r |= VT_LVAL_UNSIGNED;
4633 return r;
4636 /* indirection with full error checking and bound check */
4637 static void indir(void)
4639 if ((vtop->t & VT_BTYPE) != VT_PTR)
4640 expect("pointer");
4641 if (vtop->r & VT_LVAL)
4642 gv(RC_INT);
4643 vtop->t = pointed_type(vtop->t);
4644 /* an array is never an lvalue */
4645 if (!(vtop->t & VT_ARRAY)) {
4646 vtop->r |= lvalue_type(vtop->t);
4647 /* if bound checking, the referenced pointer must be checked */
4648 if (do_bounds_check)
4649 vtop->r |= VT_MUSTBOUND;
4653 /* pass a parameter to a function and do type checking and casting */
4654 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
4656 int func_type;
4657 func_type = func->c;
4658 if (func_type == FUNC_OLD ||
4659 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
4660 /* default casting : only need to convert float to double */
4661 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
4662 gen_cast(VT_DOUBLE);
4663 } else if (arg == NULL) {
4664 error("too many arguments to function");
4665 } else {
4666 gen_assign_cast(arg->t);
4668 gfunc_param(gf);
4671 void unary(void)
4673 int n, t, ft, fc, align, size, r, data_offset;
4674 Sym *s;
4675 GFuncContext gf;
4676 AttributeDef ad;
4678 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
4679 vpushi(tokc.i);
4680 next();
4681 } else if (tok == TOK_CUINT) {
4682 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
4683 next();
4684 } else if (tok == TOK_CLLONG) {
4685 vsetc(VT_LLONG, VT_CONST, &tokc);
4686 next();
4687 } else if (tok == TOK_CULLONG) {
4688 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
4689 next();
4690 } else if (tok == TOK_CFLOAT) {
4691 vsetc(VT_FLOAT, VT_CONST, &tokc);
4692 next();
4693 } else if (tok == TOK_CDOUBLE) {
4694 vsetc(VT_DOUBLE, VT_CONST, &tokc);
4695 next();
4696 } else if (tok == TOK_CLDOUBLE) {
4697 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
4698 next();
4699 } else if (tok == TOK___FUNC__) {
4700 void *ptr;
4701 int len;
4702 /* special function name identifier */
4704 len = strlen(funcname) + 1;
4705 /* generate char[len] type */
4706 t = VT_ARRAY | mk_pointer(VT_BYTE);
4707 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4708 s->c = len;
4709 vpush_ref(t, data_section, data_section->data_offset);
4710 ptr = section_ptr_add(data_section, len);
4711 memcpy(ptr, funcname, len);
4712 next();
4713 } else if (tok == TOK_LSTR) {
4714 t = VT_INT;
4715 goto str_init;
4716 } else if (tok == TOK_STR) {
4717 /* string parsing */
4718 t = VT_BYTE;
4719 str_init:
4720 type_size(t, &align);
4721 data_offset = data_section->data_offset;
4722 data_offset = (data_offset + align - 1) & -align;
4723 fc = data_offset;
4724 /* we must declare it as an array first to use initializer parser */
4725 t = VT_ARRAY | mk_pointer(t);
4726 decl_initializer(t, data_section, data_offset, 1, 0);
4727 data_offset += type_size(t, &align);
4728 /* XXX: is it correct to put it exactly as an array ? */
4729 vpush_ref(t, data_section, fc);
4730 data_section->data_offset = data_offset;
4731 } else {
4732 t = tok;
4733 next();
4734 if (t == '(') {
4735 /* cast ? */
4736 if (parse_btype(&t, &ad)) {
4737 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4738 skip(')');
4739 /* check ISOC99 compound literal */
4740 if (tok == '{') {
4741 /* data is allocated locally by default */
4742 if (global_expr)
4743 r = VT_CONST;
4744 else
4745 r = VT_LOCAL;
4746 /* all except arrays are lvalues */
4747 if (!(ft & VT_ARRAY))
4748 r |= lvalue_type(ft);
4749 memset(&ad, 0, sizeof(AttributeDef));
4750 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
4751 } else {
4752 unary();
4753 gen_cast(ft);
4755 } else {
4756 gexpr();
4757 skip(')');
4759 } else if (t == '*') {
4760 unary();
4761 indir();
4762 } else if (t == '&') {
4763 unary();
4764 /* functions names must be treated as function pointers,
4765 except for unary '&' and sizeof. Since we consider that
4766 functions are not lvalues, we only have to handle it
4767 there and in function calls. */
4768 /* arrays can also be used although they are not lvalues */
4769 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
4770 !(vtop->t & VT_ARRAY))
4771 test_lvalue();
4772 vtop->t = mk_pointer(vtop->t);
4773 gaddrof();
4774 } else
4775 if (t == '!') {
4776 unary();
4777 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
4778 vtop->c.i = !vtop->c.i;
4779 else if ((vtop->r & VT_VALMASK) == VT_CMP)
4780 vtop->c.i = vtop->c.i ^ 1;
4781 else
4782 vset(VT_INT, VT_JMP, gtst(1, 0));
4783 } else
4784 if (t == '~') {
4785 unary();
4786 vpushi(-1);
4787 gen_op('^');
4788 } else
4789 if (t == '+') {
4790 /* in order to force cast, we add zero */
4791 unary();
4792 if ((vtop->t & VT_BTYPE) == VT_PTR)
4793 error("pointer not accepted for unary plus");
4794 vpushi(0);
4795 gen_op('+');
4796 } else
4797 if (t == TOK_SIZEOF) {
4798 if (tok == '(') {
4799 next();
4800 if (parse_btype(&t, &ad)) {
4801 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4802 } else {
4803 /* XXX: some code could be generated: add eval
4804 flag */
4805 gexpr();
4806 t = vtop->t;
4807 vpop();
4809 skip(')');
4810 } else {
4811 unary();
4812 t = vtop->t;
4813 vpop();
4815 vpushi(type_size(t, &t));
4816 } else
4817 if (t == TOK_INC || t == TOK_DEC) {
4818 unary();
4819 inc(0, t);
4820 } else if (t == '-') {
4821 vpushi(0);
4822 unary();
4823 gen_op('-');
4824 } else
4826 if (t < TOK_UIDENT)
4827 expect("identifier");
4828 s = sym_find(t);
4829 if (!s) {
4830 if (tok != '(')
4831 error("'%s' undeclared", get_tok_str(t, NULL));
4832 /* for simple function calls, we tolerate undeclared
4833 external reference to int() function */
4834 s = external_sym(t, func_old_type, 0);
4836 vset(s->t, s->r, s->c);
4837 /* if forward reference, we must point to s */
4838 if (vtop->r & VT_SYM)
4839 vtop->c.sym = s;
4843 /* post operations */
4844 while (1) {
4845 if (tok == TOK_INC || tok == TOK_DEC) {
4846 inc(1, tok);
4847 next();
4848 } else if (tok == '.' || tok == TOK_ARROW) {
4849 /* field */
4850 if (tok == TOK_ARROW)
4851 indir();
4852 test_lvalue();
4853 gaddrof();
4854 next();
4855 /* expect pointer on structure */
4856 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
4857 expect("struct or union");
4858 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4859 /* find field */
4860 tok |= SYM_FIELD;
4861 while ((s = s->next) != NULL) {
4862 if (s->v == tok)
4863 break;
4865 if (!s)
4866 error("field not found");
4867 /* add field offset to pointer */
4868 vtop->t = char_pointer_type; /* change type to 'char *' */
4869 vpushi(s->c);
4870 gen_op('+');
4871 /* change type to field type, and set to lvalue */
4872 vtop->t = s->t;
4873 /* an array is never an lvalue */
4874 if (!(vtop->t & VT_ARRAY))
4875 vtop->r |= lvalue_type(vtop->t);
4876 next();
4877 } else if (tok == '[') {
4878 next();
4879 gexpr();
4880 gen_op('+');
4881 indir();
4882 skip(']');
4883 } else if (tok == '(') {
4884 SValue ret;
4885 Sym *sa;
4887 /* function call */
4888 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
4889 /* pointer test (no array accepted) */
4890 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4891 vtop->t = pointed_type(vtop->t);
4892 if ((vtop->t & VT_BTYPE) != VT_FUNC)
4893 goto error_func;
4894 } else {
4895 error_func:
4896 expect("function pointer");
4898 } else {
4899 vtop->r &= ~VT_LVAL; /* no lvalue */
4901 /* get return type */
4902 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
4903 save_regs(0); /* save used temporary registers */
4904 gfunc_start(&gf, s->r);
4905 next();
4906 sa = s->next; /* first parameter */
4907 #ifdef INVERT_FUNC_PARAMS
4909 int parlevel;
4910 Sym *args, *s1;
4911 ParseState saved_parse_state;
4912 TokenString str;
4914 /* read each argument and store it on a stack */
4915 /* XXX: merge it with macro args ? */
4916 args = NULL;
4917 if (tok != ')') {
4918 for(;;) {
4919 tok_str_new(&str);
4920 parlevel = 0;
4921 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
4922 tok != -1) {
4923 if (tok == '(')
4924 parlevel++;
4925 else if (tok == ')')
4926 parlevel--;
4927 tok_str_add_tok(&str);
4928 next();
4930 tok_str_add(&str, -1); /* end of file added */
4931 tok_str_add(&str, 0);
4932 s1 = sym_push2(&args, 0, 0, (int)str.str);
4933 s1->next = sa; /* add reference to argument */
4934 if (sa)
4935 sa = sa->next;
4936 if (tok == ')')
4937 break;
4938 skip(',');
4942 /* now generate code in reverse order by reading the stack */
4943 save_parse_state(&saved_parse_state);
4944 while (args) {
4945 macro_ptr = (int *)args->c;
4946 next();
4947 expr_eq();
4948 if (tok != -1)
4949 expect("',' or ')'");
4950 gfunc_param_typed(&gf, s, args->next);
4951 s1 = args->prev;
4952 free((int *)args->c);
4953 free(args);
4954 args = s1;
4956 restore_parse_state(&saved_parse_state);
4958 #endif
4959 /* compute first implicit argument if a structure is returned */
4960 if ((s->t & VT_BTYPE) == VT_STRUCT) {
4961 /* get some space for the returned structure */
4962 size = type_size(s->t, &align);
4963 loc = (loc - size) & -align;
4964 ret.t = s->t;
4965 ret.r = VT_LOCAL | VT_LVAL;
4966 /* pass it as 'int' to avoid structure arg passing
4967 problems */
4968 vset(VT_INT, VT_LOCAL, loc);
4969 ret.c = vtop->c;
4970 gfunc_param(&gf);
4971 } else {
4972 ret.t = s->t;
4973 ret.r2 = VT_CONST;
4974 /* return in register */
4975 if (is_float(ret.t)) {
4976 ret.r = REG_FRET;
4977 } else {
4978 if ((ret.t & VT_BTYPE) == VT_LLONG)
4979 ret.r2 = REG_LRET;
4980 ret.r = REG_IRET;
4982 ret.c.i = 0;
4984 #ifndef INVERT_FUNC_PARAMS
4985 if (tok != ')') {
4986 for(;;) {
4987 expr_eq();
4988 gfunc_param_typed(&gf, s, sa);
4989 if (sa)
4990 sa = sa->next;
4991 if (tok == ')')
4992 break;
4993 skip(',');
4996 #endif
4997 if (sa)
4998 error("too few arguments to function");
4999 skip(')');
5000 gfunc_call(&gf);
5001 /* return value */
5002 vsetc(ret.t, ret.r, &ret.c);
5003 vtop->r2 = ret.r2;
5004 } else {
5005 break;
5010 void uneq(void)
5012 int t;
5014 unary();
5015 if (tok == '=' ||
5016 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5017 tok == TOK_A_XOR || tok == TOK_A_OR ||
5018 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5019 test_lvalue();
5020 t = tok;
5021 next();
5022 if (t == '=') {
5023 expr_eq();
5024 } else {
5025 vdup();
5026 expr_eq();
5027 gen_op(t & 0x7f);
5029 vstore();
5033 void sum(int l)
5035 int t;
5037 if (l == 0)
5038 uneq();
5039 else {
5040 sum(--l);
5041 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5042 (l == 1 && (tok == '+' || tok == '-')) ||
5043 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5044 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5045 tok == TOK_ULT || tok == TOK_UGE)) ||
5046 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5047 (l == 5 && tok == '&') ||
5048 (l == 6 && tok == '^') ||
5049 (l == 7 && tok == '|') ||
5050 (l == 8 && tok == TOK_LAND) ||
5051 (l == 9 && tok == TOK_LOR)) {
5052 t = tok;
5053 next();
5054 sum(l);
5055 gen_op(t);
5060 /* only used if non constant */
5061 void eand(void)
5063 int t;
5065 sum(8);
5066 t = 0;
5067 while (1) {
5068 if (tok != TOK_LAND) {
5069 if (t) {
5070 t = gtst(1, t);
5071 vset(VT_INT, VT_JMPI, t);
5073 break;
5075 t = gtst(1, t);
5076 next();
5077 sum(8);
5081 void eor(void)
5083 int t;
5085 eand();
5086 t = 0;
5087 while (1) {
5088 if (tok != TOK_LOR) {
5089 if (t) {
5090 t = gtst(0, t);
5091 vset(VT_INT, VT_JMP, t);
5093 break;
5095 t = gtst(0, t);
5096 next();
5097 eand();
5101 /* XXX: better constant handling */
5102 void expr_eq(void)
5104 int t, u, c, r1, r2, rc;
5106 if (const_wanted) {
5107 sum(10);
5108 if (tok == '?') {
5109 c = vtop->c.i;
5110 vpop();
5111 next();
5112 gexpr();
5113 t = vtop->c.i;
5114 vpop();
5115 skip(':');
5116 expr_eq();
5117 if (c)
5118 vtop->c.i = t;
5120 } else {
5121 eor();
5122 if (tok == '?') {
5123 next();
5124 save_regs(1); /* we need to save all registers here except
5125 at the top because it is a branch point */
5126 t = gtst(1, 0);
5127 gexpr();
5128 /* XXX: long long handling ? */
5129 rc = RC_INT;
5130 if (is_float(vtop->t))
5131 rc = RC_FLOAT;
5132 r1 = gv(rc);
5133 vtop--; /* no vpop so that FP stack is not flushed */
5134 skip(':');
5135 u = gjmp(0);
5137 gsym(t);
5138 expr_eq();
5139 r2 = gv(rc);
5140 move_reg(r1, r2);
5141 vtop->r = r1;
5142 gsym(u);
5147 void gexpr(void)
5149 while (1) {
5150 expr_eq();
5151 if (tok != ',')
5152 break;
5153 vpop();
5154 next();
5158 /* parse a constant expression and return value in vtop */
5159 void expr_const1(void)
5161 int a;
5162 a = const_wanted;
5163 const_wanted = 1;
5164 expr_eq();
5165 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5166 expect("constant");
5167 const_wanted = a;
5170 /* parse an integer constant and return its value */
5171 int expr_const(void)
5173 int c;
5174 expr_const1();
5175 c = vtop->c.i;
5176 vpop();
5177 return c;
5180 /* return the label token if current token is a label, otherwise
5181 return zero */
5182 int is_label(void)
5184 int t;
5185 CValue c;
5187 /* fast test first */
5188 if (tok < TOK_UIDENT)
5189 return 0;
5190 /* no need to save tokc since we expect an identifier */
5191 t = tok;
5192 c = tokc;
5193 next();
5194 if (tok == ':') {
5195 next();
5196 return t;
5197 } else {
5198 /* XXX: may not work in all cases (macros ?) */
5199 tok1 = tok;
5200 tok1c = tokc;
5201 tok = t;
5202 tokc = c;
5203 return 0;
5207 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5209 int a, b, c, d;
5210 Sym *s;
5212 /* generate line number info */
5213 if (do_debug &&
5214 (last_line_num != file->line_num || last_ind != ind)) {
5215 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5216 last_ind = ind;
5217 last_line_num = file->line_num;
5220 if (tok == TOK_IF) {
5221 /* if test */
5222 next();
5223 skip('(');
5224 gexpr();
5225 skip(')');
5226 a = gtst(1, 0);
5227 block(bsym, csym, case_sym, def_sym, case_reg);
5228 c = tok;
5229 if (c == TOK_ELSE) {
5230 next();
5231 d = gjmp(0);
5232 gsym(a);
5233 block(bsym, csym, case_sym, def_sym, case_reg);
5234 gsym(d); /* patch else jmp */
5235 } else
5236 gsym(a);
5237 } else if (tok == TOK_WHILE) {
5238 next();
5239 d = ind;
5240 skip('(');
5241 gexpr();
5242 skip(')');
5243 a = gtst(1, 0);
5244 b = 0;
5245 block(&a, &b, case_sym, def_sym, case_reg);
5246 gjmp_addr(d);
5247 gsym(a);
5248 gsym_addr(b, d);
5249 } else if (tok == '{') {
5250 next();
5251 /* declarations */
5252 s = local_stack.top;
5253 while (tok != '}') {
5254 decl(VT_LOCAL);
5255 if (tok != '}')
5256 block(bsym, csym, case_sym, def_sym, case_reg);
5258 /* pop locally defined symbols */
5259 sym_pop(&local_stack, s);
5260 next();
5261 } else if (tok == TOK_RETURN) {
5262 next();
5263 if (tok != ';') {
5264 gexpr();
5265 gen_assign_cast(func_vt);
5266 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5267 /* if returning structure, must copy it to implicit
5268 first pointer arg location */
5269 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5270 indir();
5271 vswap();
5272 /* copy structure value to pointer */
5273 vstore();
5274 } else if (is_float(func_vt)) {
5275 gv(RC_FRET);
5276 } else {
5277 gv(RC_IRET);
5279 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5281 skip(';');
5282 rsym = gjmp(rsym); /* jmp */
5283 } else if (tok == TOK_BREAK) {
5284 /* compute jump */
5285 if (!bsym)
5286 error("cannot break");
5287 *bsym = gjmp(*bsym);
5288 next();
5289 skip(';');
5290 } else if (tok == TOK_CONTINUE) {
5291 /* compute jump */
5292 if (!csym)
5293 error("cannot continue");
5294 *csym = gjmp(*csym);
5295 next();
5296 skip(';');
5297 } else if (tok == TOK_FOR) {
5298 int e;
5299 next();
5300 skip('(');
5301 if (tok != ';') {
5302 gexpr();
5303 vpop();
5305 skip(';');
5306 d = ind;
5307 c = ind;
5308 a = 0;
5309 b = 0;
5310 if (tok != ';') {
5311 gexpr();
5312 a = gtst(1, 0);
5314 skip(';');
5315 if (tok != ')') {
5316 e = gjmp(0);
5317 c = ind;
5318 gexpr();
5319 vpop();
5320 gjmp_addr(d);
5321 gsym(e);
5323 skip(')');
5324 block(&a, &b, case_sym, def_sym, case_reg);
5325 gjmp_addr(c);
5326 gsym(a);
5327 gsym_addr(b, c);
5328 } else
5329 if (tok == TOK_DO) {
5330 next();
5331 a = 0;
5332 b = 0;
5333 d = ind;
5334 block(&a, &b, case_sym, def_sym, case_reg);
5335 skip(TOK_WHILE);
5336 skip('(');
5337 gsym(b);
5338 gexpr();
5339 c = gtst(0, 0);
5340 gsym_addr(c, d);
5341 skip(')');
5342 gsym(a);
5343 skip(';');
5344 } else
5345 if (tok == TOK_SWITCH) {
5346 next();
5347 skip('(');
5348 gexpr();
5349 /* XXX: other types than integer */
5350 case_reg = gv(RC_INT);
5351 vpop();
5352 skip(')');
5353 a = 0;
5354 b = gjmp(0); /* jump to first case */
5355 c = 0;
5356 block(&a, csym, &b, &c, case_reg);
5357 /* if no default, jmp after switch */
5358 if (c == 0)
5359 c = ind;
5360 /* default label */
5361 gsym_addr(b, c);
5362 /* break label */
5363 gsym(a);
5364 } else
5365 if (tok == TOK_CASE) {
5366 int v1, v2;
5367 if (!case_sym)
5368 expect("switch");
5369 next();
5370 v1 = expr_const();
5371 v2 = v1;
5372 if (gnu_ext && tok == TOK_DOTS) {
5373 next();
5374 v2 = expr_const();
5375 if (v2 < v1)
5376 warning("empty case range");
5378 /* since a case is like a label, we must skip it with a jmp */
5379 b = gjmp(0);
5380 gsym(*case_sym);
5381 vset(VT_INT, case_reg, 0);
5382 vpushi(v1);
5383 if (v1 == v2) {
5384 gen_op(TOK_EQ);
5385 *case_sym = gtst(1, 0);
5386 } else {
5387 gen_op(TOK_GE);
5388 *case_sym = gtst(1, 0);
5389 vset(VT_INT, case_reg, 0);
5390 vpushi(v2);
5391 gen_op(TOK_LE);
5392 *case_sym = gtst(1, *case_sym);
5394 gsym(b);
5395 skip(':');
5396 block(bsym, csym, case_sym, def_sym, case_reg);
5397 } else
5398 if (tok == TOK_DEFAULT) {
5399 next();
5400 skip(':');
5401 if (!def_sym)
5402 expect("switch");
5403 if (*def_sym)
5404 error("too many 'default'");
5405 *def_sym = ind;
5406 block(bsym, csym, case_sym, def_sym, case_reg);
5407 } else
5408 if (tok == TOK_GOTO) {
5409 next();
5410 s = sym_find1(&label_stack, tok);
5411 /* put forward definition if needed */
5412 if (!s)
5413 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5414 /* label already defined */
5415 if (s->t & LABEL_FORWARD)
5416 s->c = gjmp(s->c);
5417 else
5418 gjmp_addr(s->c);
5419 next();
5420 skip(';');
5421 } else {
5422 b = is_label();
5423 if (b) {
5424 /* label case */
5425 s = sym_find1(&label_stack, b);
5426 if (s) {
5427 if (!(s->t & LABEL_FORWARD))
5428 error("multiple defined label");
5429 gsym(s->c);
5430 s->c = ind;
5431 s->t = 0;
5432 } else {
5433 sym_push1(&label_stack, b, 0, ind);
5435 /* we accept this, but it is a mistake */
5436 if (tok == '}')
5437 warning("deprecated use of label at end of compound statement");
5438 else
5439 block(bsym, csym, case_sym, def_sym, case_reg);
5440 } else {
5441 /* expression case */
5442 if (tok != ';') {
5443 gexpr();
5444 vpop();
5446 skip(';');
5451 /* t is the array or struct type. c is the array or struct
5452 address. cur_index/cur_field is the pointer to the current
5453 value. 'size_only' is true if only size info is needed (only used
5454 in arrays) */
5455 void decl_designator(int t, Section *sec, unsigned long c,
5456 int *cur_index, Sym **cur_field,
5457 int size_only)
5459 Sym *s, *f;
5460 int notfirst, index, align, l;
5462 notfirst = 0;
5463 if (gnu_ext && (l = is_label()) != 0)
5464 goto struct_field;
5466 while (tok == '[' || tok == '.') {
5467 if (tok == '[') {
5468 if (!(t & VT_ARRAY))
5469 expect("array type");
5470 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5471 next();
5472 index = expr_const();
5473 if (index < 0 || (s->c >= 0 && index >= s->c))
5474 expect("invalid index");
5475 skip(']');
5476 if (!notfirst)
5477 *cur_index = index;
5478 t = pointed_type(t);
5479 c += index * type_size(t, &align);
5480 } else {
5481 next();
5482 l = tok;
5483 next();
5484 struct_field:
5485 if ((t & VT_BTYPE) != VT_STRUCT)
5486 expect("struct/union type");
5487 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5488 l |= SYM_FIELD;
5489 f = s->next;
5490 while (f) {
5491 if (f->v == l)
5492 break;
5493 f = f->next;
5495 if (!f)
5496 expect("field");
5497 if (!notfirst)
5498 *cur_field = f;
5499 t = f->t | (t & ~VT_TYPE);
5500 c += f->c;
5502 notfirst = 1;
5504 if (notfirst) {
5505 if (tok == '=') {
5506 next();
5507 } else {
5508 if (!gnu_ext)
5509 expect("=");
5511 } else {
5512 if (t & VT_ARRAY) {
5513 index = *cur_index;
5514 t = pointed_type(t);
5515 c += index * type_size(t, &align);
5516 } else {
5517 f = *cur_field;
5518 if (!f)
5519 error("too many field init");
5520 t = f->t | (t & ~VT_TYPE);
5521 c += f->c;
5524 decl_initializer(t, sec, c, 0, size_only);
5527 #define EXPR_VAL 0
5528 #define EXPR_CONST 1
5529 #define EXPR_ANY 2
5531 /* store a value or an expression directly in global data or in local array */
5532 void init_putv(int t, Section *sec, unsigned long c,
5533 int v, int expr_type)
5535 int saved_global_expr, bt;
5536 void *ptr;
5538 switch(expr_type) {
5539 case EXPR_VAL:
5540 vpushi(v);
5541 break;
5542 case EXPR_CONST:
5543 /* compound literals must be allocated globally in this case */
5544 saved_global_expr = global_expr;
5545 global_expr = 1;
5546 expr_const1();
5547 global_expr = saved_global_expr;
5548 break;
5549 case EXPR_ANY:
5550 expr_eq();
5551 break;
5554 if (sec) {
5555 /* XXX: not portable */
5556 /* XXX: generate error if incorrect relocation */
5557 gen_assign_cast(t);
5558 bt = t & VT_BTYPE;
5559 ptr = sec->data + c;
5560 if ((vtop->r & VT_SYM) &&
5561 (bt == VT_BYTE ||
5562 bt == VT_SHORT ||
5563 bt == VT_DOUBLE ||
5564 bt == VT_LDOUBLE ||
5565 bt == VT_LLONG))
5566 error("initializer element is not computable at load time");
5567 switch(bt) {
5568 case VT_BYTE:
5569 *(char *)ptr = vtop->c.i;
5570 break;
5571 case VT_SHORT:
5572 *(short *)ptr = vtop->c.i;
5573 break;
5574 case VT_DOUBLE:
5575 *(double *)ptr = vtop->c.d;
5576 break;
5577 case VT_LDOUBLE:
5578 *(long double *)ptr = vtop->c.ld;
5579 break;
5580 case VT_LLONG:
5581 *(long long *)ptr = vtop->c.ll;
5582 break;
5583 default:
5584 if (vtop->r & VT_SYM) {
5585 greloc(sec, vtop->c.sym, c, R_DATA_32);
5586 *(int *)ptr = 0;
5587 } else {
5588 *(int *)ptr = vtop->c.i;
5590 break;
5592 vtop--;
5593 } else {
5594 vset(t, VT_LOCAL, c);
5595 vswap();
5596 vstore();
5597 vpop();
5601 /* put zeros for variable based init */
5602 void init_putz(int t, Section *sec, unsigned long c, int size)
5604 GFuncContext gf;
5606 if (sec) {
5607 /* nothing to do because globals are already set to zero */
5608 } else {
5609 gfunc_start(&gf, FUNC_CDECL);
5610 vpushi(size);
5611 gfunc_param(&gf);
5612 vpushi(0);
5613 gfunc_param(&gf);
5614 vset(VT_INT, VT_LOCAL, c);
5615 gfunc_param(&gf);
5616 vpush_sym(func_old_type, TOK_memset);
5617 gfunc_call(&gf);
5621 /* 't' contains the type and storage info. 'c' is the offset of the
5622 object in section 'sec'. If 'sec' is NULL, it means stack based
5623 allocation. 'first' is true if array '{' must be read (multi
5624 dimension implicit array init handling). 'size_only' is true if
5625 size only evaluation is wanted (only for arrays). */
5626 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only)
5628 int index, array_length, n, no_oblock, nb, parlevel, i;
5629 int t1, size1, align1, expr_type;
5630 Sym *s, *f;
5631 TokenSym *ts;
5633 if (t & VT_ARRAY) {
5634 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5635 n = s->c;
5636 array_length = 0;
5637 t1 = pointed_type(t);
5638 size1 = type_size(t1, &align1);
5640 no_oblock = 1;
5641 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5642 tok == '{') {
5643 skip('{');
5644 no_oblock = 0;
5647 /* only parse strings here if correct type (otherwise: handle
5648 them as ((w)char *) expressions */
5649 if ((tok == TOK_LSTR &&
5650 (t1 & VT_BTYPE) == VT_INT) ||
5651 (tok == TOK_STR &&
5652 (t1 & VT_BTYPE) == VT_BYTE)) {
5653 /* XXX: move multiple string parsing in parser ? */
5654 while (tok == TOK_STR || tok == TOK_LSTR) {
5655 ts = tokc.ts;
5656 /* compute maximum number of chars wanted */
5657 nb = ts->len;
5658 if (n >= 0 && nb > (n - array_length))
5659 nb = n - array_length;
5660 if (!size_only) {
5661 if (ts->len > nb)
5662 warning("initializer-string for array is too long");
5663 for(i=0;i<nb;i++) {
5664 init_putv(t1, sec, c + (array_length + i) * size1,
5665 ts->str[i], EXPR_VAL);
5668 array_length += nb;
5669 next();
5671 /* only add trailing zero if enough storage (no
5672 warning in this case since it is standard) */
5673 if (n < 0 || array_length < n) {
5674 if (!size_only) {
5675 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5677 array_length++;
5679 } else {
5680 index = 0;
5681 while (tok != '}') {
5682 decl_designator(t, sec, c, &index, NULL, size_only);
5683 if (n >= 0 && index >= n)
5684 error("index too large");
5685 /* must put zero in holes (note that doing it that way
5686 ensures that it even works with designators) */
5687 if (!size_only && array_length < index) {
5688 init_putz(t1, sec, c + array_length * size1,
5689 (index - array_length) * size1);
5691 index++;
5692 if (index > array_length)
5693 array_length = index;
5694 /* special test for multi dimensional arrays (may not
5695 be strictly correct if designators are used at the
5696 same time) */
5697 if (index >= n && no_oblock)
5698 break;
5699 if (tok == '}')
5700 break;
5701 skip(',');
5704 if (!no_oblock)
5705 skip('}');
5706 /* put zeros at the end */
5707 if (!size_only && n >= 0 && array_length < n) {
5708 init_putz(t1, sec, c + array_length * size1,
5709 (n - array_length) * size1);
5711 /* patch type size if needed */
5712 if (n < 0)
5713 s->c = array_length;
5714 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
5715 /* XXX: union needs only one init */
5716 next();
5717 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5718 f = s->next;
5719 array_length = 0;
5720 index = 0;
5721 n = s->c;
5722 while (tok != '}') {
5723 decl_designator(t, sec, c, NULL, &f, size_only);
5724 /* fill with zero between fields */
5725 index = f->c;
5726 if (!size_only && array_length < index) {
5727 init_putz(t, sec, c + array_length,
5728 index - array_length);
5730 index = index + type_size(f->t, &align1);
5731 if (index > array_length)
5732 array_length = index;
5733 if (tok == '}')
5734 break;
5735 skip(',');
5736 f = f->next;
5738 /* put zeros at the end */
5739 if (!size_only && array_length < n) {
5740 init_putz(t, sec, c + array_length,
5741 n - array_length);
5743 skip('}');
5744 } else if (tok == '{') {
5745 next();
5746 decl_initializer(t, sec, c, first, size_only);
5747 skip('}');
5748 } else if (size_only) {
5749 /* just skip expression */
5750 parlevel = 0;
5751 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
5752 tok != -1) {
5753 if (tok == '(')
5754 parlevel++;
5755 else if (tok == ')')
5756 parlevel--;
5757 next();
5759 } else {
5760 /* currently, we always use constant expression for globals
5761 (may change for scripting case) */
5762 expr_type = EXPR_CONST;
5763 if (!sec)
5764 expr_type = EXPR_ANY;
5765 init_putv(t, sec, c, 0, expr_type);
5769 /* parse an initializer for type 't' if 'has_init' is true, and
5770 allocate space in local or global data space ('r' is either
5771 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5772 variable 'v' of scope 'scope' is declared before initializers are
5773 parsed. If 'v' is zero, then a reference to the new object is put
5774 in the value stack. */
5775 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
5776 int v, int scope)
5778 int size, align, addr, data_offset;
5779 int level;
5780 ParseState saved_parse_state;
5781 TokenString init_str;
5782 Section *sec;
5784 size = type_size(t, &align);
5785 /* If unknown size, we must evaluate it before
5786 evaluating initializers because
5787 initializers can generate global data too
5788 (e.g. string pointers or ISOC99 compound
5789 literals). It also simplifies local
5790 initializers handling */
5791 tok_str_new(&init_str);
5792 if (size < 0) {
5793 if (!has_init)
5794 error("unknown type size");
5795 /* get all init string */
5796 level = 0;
5797 while (level > 0 || (tok != ',' && tok != ';')) {
5798 if (tok < 0)
5799 error("unexpected end of file in initializer");
5800 tok_str_add_tok(&init_str);
5801 if (tok == '{')
5802 level++;
5803 else if (tok == '}') {
5804 if (level == 0)
5805 break;
5806 level--;
5808 next();
5810 tok_str_add(&init_str, -1);
5811 tok_str_add(&init_str, 0);
5813 /* compute size */
5814 save_parse_state(&saved_parse_state);
5816 macro_ptr = init_str.str;
5817 next();
5818 decl_initializer(t, NULL, 0, 1, 1);
5819 /* prepare second initializer parsing */
5820 macro_ptr = init_str.str;
5821 next();
5823 /* if still unknown size, error */
5824 size = type_size(t, &align);
5825 if (size < 0)
5826 error("unknown type size");
5828 /* take into account specified alignment if bigger */
5829 if (ad->aligned > align)
5830 align = ad->aligned;
5831 if ((r & VT_VALMASK) == VT_LOCAL) {
5832 sec = NULL;
5833 if (do_bounds_check && (t & VT_ARRAY))
5834 loc--;
5835 #ifdef TCC_TARGET_IL
5836 /* XXX: ugly patch to allocate local variables for IL, just
5837 for testing */
5838 addr = loc;
5839 loc++;
5840 #else
5841 loc = (loc - size) & -align;
5842 addr = loc;
5843 #endif
5844 /* handles bounds */
5845 /* XXX: currently, since we do only one pass, we cannot track
5846 '&' operators, so we add only arrays */
5847 if (do_bounds_check && (t & VT_ARRAY)) {
5848 unsigned long *bounds_ptr;
5849 /* add padding between regions */
5850 loc--;
5851 /* then add local bound info */
5852 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5853 bounds_ptr[0] = addr;
5854 bounds_ptr[1] = size;
5856 } else {
5857 /* compute section */
5858 sec = ad->section;
5859 if (!sec) {
5860 if (has_init)
5861 sec = data_section;
5862 else
5863 sec = bss_section;
5865 data_offset = sec->data_offset;
5866 data_offset = (data_offset + align - 1) & -align;
5867 addr = data_offset;
5868 /* very important to increment global pointer at this time
5869 because initializers themselves can create new initializers */
5870 data_offset += size;
5871 /* add padding if bound check */
5872 if (do_bounds_check)
5873 data_offset++;
5874 sec->data_offset = data_offset;
5876 if (!sec) {
5877 if (v) {
5878 /* local variable */
5879 sym_push(v, t, r, addr);
5880 } else {
5881 /* push local reference */
5882 vset(t, r, addr);
5884 } else {
5885 Sym *sym;
5887 if (v) {
5888 if (scope == VT_CONST) {
5889 /* global scope: see if already defined */
5890 sym = sym_find(v);
5891 if (!sym)
5892 goto do_def;
5893 if (!is_compatible_types(sym->t, t))
5894 error("incompatible types for redefinition of '%s'",
5895 get_tok_str(v, NULL));
5896 if (!(sym->t & VT_EXTERN))
5897 error("redefinition of '%s'", get_tok_str(v, NULL));
5898 sym->t &= ~VT_EXTERN;
5899 } else {
5900 do_def:
5901 sym = sym_push(v, t, r | VT_SYM, 0);
5903 put_extern_sym(sym, sec, addr);
5904 } else {
5905 CValue cval;
5907 /* push global reference */
5908 sym = get_sym_ref(t, sec, addr, 0);
5909 cval.sym = sym;
5910 vsetc(t, VT_CONST | VT_SYM, &cval);
5913 /* handles bounds now because the symbol must be defined
5914 before for the relocation */
5915 if (do_bounds_check) {
5916 unsigned long *bounds_ptr;
5918 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
5919 /* then add global bound info */
5920 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5921 bounds_ptr[0] = 0; /* relocated */
5922 bounds_ptr[1] = size;
5925 if (has_init) {
5926 decl_initializer(t, sec, addr, 1, 0);
5927 /* restore parse state if needed */
5928 if (init_str.str) {
5929 free(init_str.str);
5930 restore_parse_state(&saved_parse_state);
5935 void put_func_debug(Sym *sym)
5937 char buf[512];
5939 /* stabs info */
5940 /* XXX: we put here a dummy type */
5941 snprintf(buf, sizeof(buf), "%s:%c1",
5942 funcname, sym->t & VT_STATIC ? 'f' : 'F');
5943 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5944 cur_text_section, sym->c);
5945 func_ind = ind;
5946 last_ind = 0;
5947 last_line_num = 0;
5950 /* not finished : try to put some local vars in registers */
5951 //#define CONFIG_REG_VARS
5953 #ifdef CONFIG_REG_VARS
5954 void add_var_ref(int t)
5956 printf("%s:%d: &%s\n",
5957 file->filename, file->line_num,
5958 get_tok_str(t, NULL));
5961 /* first pass on a function with heuristic to extract variable usage
5962 and pointer references to local variables for register allocation */
5963 void analyse_function(void)
5965 int level, t;
5967 for(;;) {
5968 if (tok == -1)
5969 break;
5970 /* any symbol coming after '&' is considered as being a
5971 variable whose reference is taken. It is highly unaccurate
5972 but it is difficult to do better without a complete parse */
5973 if (tok == '&') {
5974 next();
5975 /* if '& number', then no need to examine next tokens */
5976 if (tok == TOK_CINT ||
5977 tok == TOK_CUINT ||
5978 tok == TOK_CLLONG ||
5979 tok == TOK_CULLONG) {
5980 continue;
5981 } else if (tok >= TOK_UIDENT) {
5982 /* if '& ident [' or '& ident ->', then ident address
5983 is not needed */
5984 t = tok;
5985 next();
5986 if (tok != '[' && tok != TOK_ARROW)
5987 add_var_ref(t);
5988 } else {
5989 level = 0;
5990 while (tok != '}' && tok != ';' &&
5991 !((tok == ',' || tok == ')') && level == 0)) {
5992 if (tok >= TOK_UIDENT) {
5993 add_var_ref(tok);
5994 } else if (tok == '(') {
5995 level++;
5996 } else if (tok == ')') {
5997 level--;
5999 next();
6002 } else {
6003 next();
6007 #endif
6009 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6010 void decl(int l)
6012 int t, b, v, has_init, r;
6013 Sym *sym;
6014 AttributeDef ad;
6016 while (1) {
6017 if (!parse_btype(&b, &ad)) {
6018 /* skip redundant ';' */
6019 /* XXX: find more elegant solution */
6020 if (tok == ';') {
6021 next();
6022 continue;
6024 /* special test for old K&R protos without explicit int
6025 type. Only accepted when defining global data */
6026 if (l == VT_LOCAL || tok < TOK_DEFINE)
6027 break;
6028 b = VT_INT;
6030 if (((b & VT_BTYPE) == VT_ENUM ||
6031 (b & VT_BTYPE) == VT_STRUCT) &&
6032 tok == ';') {
6033 /* we accept no variable after */
6034 next();
6035 continue;
6037 while (1) { /* iterate thru each declaration */
6038 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6039 #if 0
6041 char buf[500];
6042 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6043 printf("type = '%s'\n", buf);
6045 #endif
6046 if (tok == '{') {
6047 #ifdef CONFIG_REG_VARS
6048 TokenString func_str;
6049 ParseState saved_parse_state;
6050 int block_level;
6051 #endif
6053 if (l == VT_LOCAL)
6054 error("cannot use local functions");
6055 if (!(t & VT_FUNC))
6056 expect("function definition");
6058 #ifdef CONFIG_REG_VARS
6059 /* parse all function code and record it */
6061 tok_str_new(&func_str);
6063 block_level = 0;
6064 for(;;) {
6065 int t;
6066 if (tok == -1)
6067 error("unexpected end of file");
6068 tok_str_add_tok(&func_str);
6069 t = tok;
6070 next();
6071 if (t == '{') {
6072 block_level++;
6073 } else if (t == '}') {
6074 block_level--;
6075 if (block_level == 0)
6076 break;
6079 tok_str_add(&func_str, -1);
6080 tok_str_add(&func_str, 0);
6082 save_parse_state(&saved_parse_state);
6084 macro_ptr = func_str.str;
6085 next();
6086 analyse_function();
6087 #endif
6089 /* compute text section */
6090 cur_text_section = ad.section;
6091 if (!cur_text_section)
6092 cur_text_section = text_section;
6093 ind = cur_text_section->data_offset;
6094 funcname = get_tok_str(v, NULL);
6095 sym = sym_find(v);
6096 if (sym) {
6097 /* if symbol is already defined, then put complete type */
6098 sym->t = t;
6099 } else {
6100 /* put function symbol */
6101 sym = sym_push1(&global_stack, v, t, 0);
6103 put_extern_sym(sym, cur_text_section, ind);
6104 sym->r = VT_SYM | VT_CONST;
6105 /* put debug symbol */
6106 if (do_debug)
6107 put_func_debug(sym);
6108 /* push a dummy symbol to enable local sym storage */
6109 sym_push1(&local_stack, 0, 0, 0);
6110 gfunc_prolog(t);
6111 loc = 0;
6112 rsym = 0;
6113 #ifdef CONFIG_REG_VARS
6114 macro_ptr = func_str.str;
6115 next();
6116 #endif
6117 block(NULL, NULL, NULL, NULL, 0);
6118 gsym(rsym);
6119 gfunc_epilog();
6120 cur_text_section->data_offset = ind;
6121 sym_pop(&label_stack, NULL); /* reset label stack */
6122 sym_pop(&local_stack, NULL); /* reset local stack */
6123 /* end of function */
6124 if (do_debug) {
6125 put_stabn(N_FUN, 0, 0, ind - func_ind);
6127 funcname = ""; /* for safety */
6128 func_vt = VT_VOID; /* for safety */
6129 ind = 0; /* for safety */
6131 #ifdef CONFIG_REG_VARS
6132 free(func_str.str);
6133 restore_parse_state(&saved_parse_state);
6134 #endif
6135 break;
6136 } else {
6137 if (b & VT_TYPEDEF) {
6138 /* save typedefed type */
6139 /* XXX: test storage specifiers ? */
6140 sym_push(v, t | VT_TYPEDEF, 0, 0);
6141 } else if ((t & VT_BTYPE) == VT_FUNC) {
6142 /* external function definition */
6143 external_sym(v, t, 0);
6144 } else {
6145 /* not lvalue if array */
6146 r = 0;
6147 if (!(t & VT_ARRAY))
6148 r |= lvalue_type(t);
6149 if (b & VT_EXTERN) {
6150 /* external variable */
6151 external_sym(v, t, r);
6152 } else {
6153 if (t & VT_STATIC)
6154 r |= VT_CONST;
6155 else
6156 r |= l;
6157 has_init = (tok == '=');
6158 if (has_init)
6159 next();
6160 decl_initializer_alloc(t, &ad, r,
6161 has_init, v, l);
6164 if (tok != ',') {
6165 skip(';');
6166 break;
6168 next();
6174 /* compile the C file opened in 'file'. Return non zero if errors. */
6175 static int tcc_compile(TCCState *s)
6177 Sym *define_start;
6178 char buf[512];
6179 int p, section_sym;
6181 funcname = "";
6182 include_stack_ptr = include_stack;
6183 ifdef_stack_ptr = ifdef_stack;
6185 vtop = vstack - 1;
6186 anon_sym = SYM_FIRST_ANOM;
6188 /* file info: full path + filename */
6189 section_sym = 0; /* avoid warning */
6190 if (do_debug) {
6191 section_sym = put_elf_sym(symtab_section, 0, 0,
6192 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
6193 text_section->sh_num, NULL);
6194 getcwd(buf, sizeof(buf));
6195 pstrcat(buf, sizeof(buf), "/");
6196 put_stabs_r(buf, N_SO, 0, 0,
6197 text_section->data_offset, text_section, section_sym);
6198 put_stabs_r(file->filename, N_SO, 0, 0,
6199 text_section->data_offset, text_section, section_sym);
6201 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6202 symbols can be safely used */
6203 put_elf_sym(symtab_section, 0, 0,
6204 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6205 SHN_ABS, file->filename);
6207 /* define common 'char *' type because it is often used internally
6208 for arrays and struct dereference */
6209 char_pointer_type = mk_pointer(VT_BYTE);
6210 /* define an old type function 'int func()' */
6211 p = anon_sym++;
6212 sym_push1(&global_stack, p, 0, FUNC_OLD);
6213 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
6215 define_start = define_stack.top;
6216 inp();
6217 ch = '\n'; /* needed to parse correctly first preprocessor command */
6218 next();
6219 decl(VT_CONST);
6220 if (tok != -1)
6221 expect("declaration");
6223 /* end of translation unit info */
6224 if (do_debug) {
6225 put_stabs_r(NULL, N_SO, 0, 0,
6226 text_section->data_offset, text_section, section_sym);
6229 /* reset define stack, but leave -Dsymbols (may be incorrect if
6230 they are undefined) */
6231 sym_pop(&define_stack, define_start);
6233 sym_pop(&global_stack, NULL);
6235 return 0;
6238 int tcc_compile_string(TCCState *s, const char *str)
6240 BufferedFile bf1, *bf = &bf1;
6241 int ret;
6243 /* init file structure */
6244 bf->fd = -1;
6245 bf->buf_ptr = (char *)str;
6246 bf->buf_end = (char *)str + strlen(bf->buffer);
6247 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6248 bf->line_num = 1;
6249 file = bf;
6251 ret = tcc_compile(s);
6253 /* currently, no need to close */
6254 return ret;
6257 /* define a symbol. A value can also be provided with the '=' operator */
6258 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6260 BufferedFile bf1, *bf = &bf1;
6262 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6263 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6264 /* default value */
6265 if (!value)
6266 value = "1";
6267 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6269 /* init file structure */
6270 bf->fd = -1;
6271 bf->buf_ptr = bf->buffer;
6272 bf->buf_end = bf->buffer + strlen(bf->buffer);
6273 bf->filename[0] = '\0';
6274 bf->line_num = 1;
6275 file = bf;
6277 include_stack_ptr = include_stack;
6279 /* parse with define parser */
6280 inp();
6281 ch = '\n'; /* needed to parse correctly first preprocessor command */
6282 next_nomacro();
6283 parse_define();
6284 file = NULL;
6287 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6289 TokenSym *ts;
6290 Sym *s;
6291 ts = tok_alloc(sym, 0);
6292 s = sym_find1(&define_stack, tok);
6293 /* undefine symbol by putting an invalid name */
6294 if (s)
6295 sym_undef(&define_stack, s);
6298 static int put_elf_str(Section *s, const char *sym)
6300 int offset, len;
6301 char *ptr;
6303 len = strlen(sym) + 1;
6304 offset = s->data_offset;
6305 ptr = section_ptr_add(s, len);
6306 memcpy(ptr, sym, len);
6307 return offset;
6310 /* elf symbol hashing function */
6311 static unsigned long elf_hash(const unsigned char *name)
6313 unsigned long h = 0, g;
6315 while (*name) {
6316 h = (h << 4) + *name++;
6317 g = h & 0xf0000000;
6318 if (g)
6319 h ^= g >> 24;
6320 h &= ~g;
6322 return h;
6325 /* return the symbol number */
6326 static int put_elf_sym(Section *s,
6327 unsigned long value, unsigned long size,
6328 int info, int other, int shndx, const char *name)
6330 int name_offset, sym_index;
6331 int nbuckets, h;
6332 Elf32_Sym *sym;
6333 Section *hs;
6335 sym = section_ptr_add(s, sizeof(Elf32_Sym));
6336 if (name)
6337 name_offset = put_elf_str(s->link, name);
6338 else
6339 name_offset = 0;
6340 /* XXX: endianness */
6341 sym->st_name = name_offset;
6342 sym->st_value = value;
6343 sym->st_size = size;
6344 sym->st_info = info;
6345 sym->st_other = other;
6346 sym->st_shndx = shndx;
6347 sym_index = sym - (Elf32_Sym *)s->data;
6348 hs = s->hash;
6349 if (hs) {
6350 int *ptr;
6351 ptr = section_ptr_add(hs, sizeof(int));
6352 /* only add global or weak symbols */
6353 if (ELF32_ST_BIND(info) != STB_LOCAL) {
6354 /* add another hashing entry */
6355 nbuckets = ((int *)hs->data)[0];
6356 h = elf_hash(name) % nbuckets;
6357 *ptr = ((int *)hs->data)[2 + h];
6358 ((int *)hs->data)[2 + h] = sym_index;
6359 } else {
6360 *ptr = 0;
6362 /* but still add room for all symbols */
6363 ((int *)hs->data)[1]++;
6365 return sym_index;
6368 /* find global ELF symbol 'name' and return its index. Return 0 if not
6369 found. */
6370 static int find_elf_sym(Section *s, const char *name)
6372 Elf32_Sym *sym;
6373 Section *hs;
6374 int nbuckets, sym_index, h;
6375 const char *name1;
6377 hs = s->hash;
6378 if (!hs)
6379 return 0;
6380 nbuckets = ((int *)hs->data)[0];
6381 h = elf_hash(name) % nbuckets;
6382 sym_index = ((int *)hs->data)[2 + h];
6383 while (sym_index != 0) {
6384 sym = &((Elf32_Sym *)s->data)[sym_index];
6385 name1 = s->link->data + sym->st_name;
6386 if (!strcmp(name, name1))
6387 return sym_index;
6388 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
6390 return 0;
6393 /* return elf symbol value or error */
6394 static unsigned long get_elf_sym_val(const char *name)
6396 int sym_index;
6397 Elf32_Sym *sym;
6399 sym_index = find_elf_sym(symtab_section, name);
6400 if (!sym_index)
6401 error("%s not defined", name);
6402 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6403 return sym->st_value;
6406 /* add an elf symbol : check if it is already defined and patch
6407 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6408 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
6409 int info, int sh_num, const char *name)
6411 Elf32_Sym *esym;
6412 int sym_bind, sym_index, sym_type, esym_bind;
6414 sym_bind = ELF32_ST_BIND(info);
6415 sym_type = ELF32_ST_TYPE(info);
6417 if (sym_bind != STB_LOCAL) {
6418 /* we search global or weak symbols */
6419 sym_index = find_elf_sym(s, name);
6420 if (!sym_index)
6421 goto do_def;
6422 esym = &((Elf32_Sym *)s->data)[sym_index];
6423 if (esym->st_shndx != SHN_UNDEF) {
6424 esym_bind = ELF32_ST_BIND(esym->st_info);
6425 if (sh_num == SHN_UNDEF) {
6426 /* ignore adding of undefined symbol if the
6427 corresponding symbol is already defined */
6428 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
6429 /* global overrides weak, so patch */
6430 goto do_patch;
6431 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
6432 /* weak is ignored if already global */
6433 } else {
6434 #if 0
6435 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6436 sym_bind, sh_num, esym_bind, esym->st_shndx);
6437 #endif
6438 /* NOTE: we accept that two DLL define the same symbol */
6439 if (s != dynsymtab_section)
6440 error("'%s' defined twice", name);
6442 } else {
6443 do_patch:
6444 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
6445 esym->st_shndx = sh_num;
6446 esym->st_value = value;
6447 esym->st_size = size;
6449 } else {
6450 do_def:
6451 sym_index = put_elf_sym(s, value, size,
6452 ELF32_ST_INFO(sym_bind, sym_type), 0,
6453 sh_num, name);
6455 return sym_index;
6458 /* update sym->c so that it points to an external symbol in section
6459 'section' with value 'value' */
6460 void put_extern_sym(Sym *sym, Section *section, unsigned long value)
6462 int sym_type, sym_bind, sh_num, info;
6463 Elf32_Sym *esym;
6464 const char *name;
6465 char buf[32];
6467 if (section)
6468 sh_num = section->sh_num;
6469 else
6470 sh_num = SHN_UNDEF;
6471 if (!sym->c) {
6472 if ((sym->t & VT_BTYPE) == VT_FUNC)
6473 sym_type = STT_FUNC;
6474 else
6475 sym_type = STT_OBJECT;
6476 if (sym->t & VT_STATIC)
6477 sym_bind = STB_LOCAL;
6478 else
6479 sym_bind = STB_GLOBAL;
6481 name = get_tok_str(sym->v, NULL);
6482 #ifdef CONFIG_TCC_BCHECK
6483 if (do_bounds_check) {
6484 /* if bound checking is activated, we change some function
6485 names by adding the "__bound" prefix */
6486 switch(sym->v) {
6487 case TOK_malloc:
6488 case TOK_free:
6489 case TOK_realloc:
6490 case TOK_memalign:
6491 case TOK_calloc:
6492 case TOK_memcpy:
6493 case TOK_memmove:
6494 case TOK_memset:
6495 case TOK_strlen:
6496 case TOK_strcpy:
6497 strcpy(buf, "__bound_");
6498 strcat(buf, name);
6499 name = buf;
6500 break;
6503 #endif
6504 info = ELF32_ST_INFO(sym_bind, sym_type);
6505 sym->c = add_elf_sym(symtab_section, value, 0, info, sh_num, name);
6506 } else {
6507 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6508 esym->st_value = value;
6509 esym->st_shndx = sh_num;
6513 /* put relocation */
6514 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
6515 int type, int symbol)
6517 char buf[256];
6518 Section *sr;
6519 Elf32_Rel *rel;
6521 sr = s->reloc;
6522 if (!sr) {
6523 /* if no relocation section, create it */
6524 snprintf(buf, sizeof(buf), ".rel%s", s->name);
6525 /* if the symtab is allocated, then we consider the relocation
6526 are also */
6527 sr = new_section(buf, SHT_REL, symtab->sh_flags);
6528 sr->sh_entsize = sizeof(Elf32_Rel);
6529 sr->link = symtab;
6530 sr->sh_info = s->sh_num;
6531 s->reloc = sr;
6533 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
6534 rel->r_offset = offset;
6535 rel->r_info = ELF32_R_INFO(symbol, type);
6538 /* put stab debug information */
6540 typedef struct {
6541 unsigned long n_strx; /* index into string table of name */
6542 unsigned char n_type; /* type of symbol */
6543 unsigned char n_other; /* misc info (usually empty) */
6544 unsigned short n_desc; /* description field */
6545 unsigned long n_value; /* value of symbol */
6546 } Stab_Sym;
6548 static void put_stabs(const char *str, int type, int other, int desc,
6549 unsigned long value)
6551 Stab_Sym *sym;
6553 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
6554 if (str) {
6555 sym->n_strx = put_elf_str(stabstr_section, str);
6556 } else {
6557 sym->n_strx = 0;
6559 sym->n_type = type;
6560 sym->n_other = other;
6561 sym->n_desc = desc;
6562 sym->n_value = value;
6565 static void put_stabs_r(const char *str, int type, int other, int desc,
6566 unsigned long value, Section *sec, int sym_index)
6568 put_stabs(str, type, other, desc, value);
6569 put_elf_reloc(symtab_section, stab_section,
6570 stab_section->data_offset - sizeof(unsigned long),
6571 R_DATA_32, sym_index);
6574 static void put_stabn(int type, int other, int desc, int value)
6576 put_stabs(NULL, type, other, desc, value);
6579 static void put_stabd(int type, int other, int desc)
6581 put_stabs(NULL, type, other, desc, 0);
6584 /* In an ELF file symbol table, the local symbols must appear below
6585 the global and weak ones. Since TCC cannot sort it while generating
6586 the code, we must do it after. All the relocation tables are also
6587 modified to take into account the symbol table sorting */
6588 static void sort_syms(Section *s)
6590 int *old_to_new_syms;
6591 Elf32_Sym *new_syms;
6592 int nb_syms, i;
6593 Elf32_Sym *p, *q;
6594 Elf32_Rel *rel, *rel_end;
6595 Section *sr;
6596 int type, sym_index;
6598 nb_syms = s->data_offset / sizeof(Elf32_Sym);
6599 new_syms = malloc(nb_syms * sizeof(Elf32_Sym));
6600 if (!new_syms)
6601 error("memory full");
6602 old_to_new_syms = malloc(nb_syms * sizeof(int));
6603 if (!old_to_new_syms)
6604 error("memory full");
6605 /* first pass for local symbols */
6606 p = (Elf32_Sym *)s->data;
6607 q = new_syms;
6608 for(i = 0; i < nb_syms; i++) {
6609 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
6610 old_to_new_syms[i] = q - new_syms;
6611 *q++ = *p;
6613 p++;
6615 /* save the number of local symbols in section header */
6616 s->sh_info = q - new_syms;
6618 /* then second pass for non local symbols */
6619 p = (Elf32_Sym *)s->data;
6620 for(i = 0; i < nb_syms; i++) {
6621 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
6622 old_to_new_syms[i] = q - new_syms;
6623 *q++ = *p;
6625 p++;
6628 /* we copy the new symbols to the old */
6629 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
6630 free(new_syms);
6632 /* now we modify all the relocations */
6633 for(i = 1; i < nb_sections; i++) {
6634 sr = sections[i];
6635 if (sr->sh_type == SHT_REL && sr->link == s) {
6636 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6637 for(rel = (Elf32_Rel *)sr->data;
6638 rel < rel_end;
6639 rel++) {
6640 sym_index = ELF32_R_SYM(rel->r_info);
6641 type = ELF32_R_TYPE(rel->r_info);
6642 sym_index = old_to_new_syms[sym_index];
6643 rel->r_info = ELF32_R_INFO(sym_index, type);
6648 free(old_to_new_syms);
6651 /* relocate common symbols in the .bss section */
6652 static void relocate_common_syms(void)
6654 Elf32_Sym *sym, *sym_end;
6655 unsigned long offset, align;
6657 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
6658 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6659 sym < sym_end;
6660 sym++) {
6661 if (sym->st_shndx == SHN_COMMON) {
6662 /* align symbol */
6663 align = sym->st_value;
6664 offset = bss_section->data_offset;
6665 offset = (offset + align - 1) & -align;
6666 sym->st_value = offset;
6667 sym->st_shndx = bss_section->sh_num;
6668 offset += sym->st_size;
6669 bss_section->data_offset = offset;
6674 static void *resolve_sym(const char *sym)
6676 return dlsym(NULL, sym);
6679 /* relocate symbol table, resolve undefined symbols if do_resolve is
6680 true and output error if undefined symbol. */
6681 static void relocate_syms(int do_resolve)
6683 Elf32_Sym *sym, *esym, *sym_end;
6684 int sym_bind, sh_num, sym_index;
6685 const char *name;
6686 unsigned long addr;
6688 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
6689 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6690 sym < sym_end;
6691 sym++) {
6692 sh_num = sym->st_shndx;
6693 if (sh_num == SHN_UNDEF) {
6694 name = strtab_section->data + sym->st_name;
6695 if (do_resolve) {
6696 name = symtab_section->link->data + sym->st_name;
6697 addr = (unsigned long)resolve_sym(name);
6698 if (addr) {
6699 sym->st_value = addr;
6700 goto found;
6702 } else if (dynsym) {
6703 /* if dynamic symbol exist, then use it */
6704 sym_index = find_elf_sym(dynsym, name);
6705 if (sym_index) {
6706 esym = &((Elf32_Sym *)dynsym->data)[sym_index];
6707 sym->st_value = esym->st_value;
6708 goto found;
6711 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
6712 it */
6713 if (!strcmp(name, "_fp_hw"))
6714 goto found;
6715 /* only weak symbols are accepted to be undefined. Their
6716 value is zero */
6717 sym_bind = ELF32_ST_BIND(sym->st_info);
6718 if (sym_bind == STB_WEAK) {
6719 sym->st_value = 0;
6720 } else {
6721 error("undefined symbol '%s'", name);
6723 } else if (sh_num < SHN_LORESERVE) {
6724 /* add section base */
6725 sym->st_value += sections[sym->st_shndx]->sh_addr;
6727 found: ;
6731 /* elf relocation, CPU dependant */
6732 static void elf_reloc(unsigned char *ptr,
6733 unsigned long addr, unsigned long val, int type,
6734 int sym_index)
6736 switch(type) {
6737 case R_386_32:
6738 *(int *)ptr += val;
6739 break;
6740 case R_386_PLT32:
6741 case R_386_PC32:
6742 *(int *)ptr += val - addr;
6743 break;
6744 case R_386_GLOB_DAT:
6745 case R_386_JMP_SLOT:
6746 *(int *)ptr = val;
6747 break;
6748 case R_386_GOTPC:
6749 *(int *)ptr += got->sh_addr - addr;
6750 break;
6751 case R_386_GOTOFF:
6752 *(int *)ptr += val - got->sh_addr;
6753 break;
6754 case R_386_GOT32:
6755 /* we load the got offset */
6756 *(int *)ptr += got_offsets[sym_index];
6757 break;
6762 /* relocate a given section */
6763 static void relocate_section(Section *s)
6765 Section *sr;
6766 Elf32_Rel *rel, *rel_end;
6767 Elf32_Sym *sym;
6768 int type, sym_index;
6769 unsigned char *ptr;
6770 unsigned long val;
6772 sr = s->reloc;
6773 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6774 for(rel = (Elf32_Rel *)sr->data;
6775 rel < rel_end;
6776 rel++) {
6777 ptr = s->data + rel->r_offset;
6779 sym_index = ELF32_R_SYM(rel->r_info);
6780 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6781 val = sym->st_value;
6782 type = ELF32_R_TYPE(rel->r_info);
6783 elf_reloc(ptr, s->sh_addr + rel->r_offset, val, type, sym_index);
6787 /* relocate relocation table in 'sr' */
6788 static void relocate_rel(Section *sr)
6790 Section *s;
6791 Elf32_Rel *rel, *rel_end;
6793 s = sections[sr->sh_info];
6794 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6795 for(rel = (Elf32_Rel *)sr->data;
6796 rel < rel_end;
6797 rel++) {
6798 rel->r_offset += s->sh_addr;
6802 static void put_got_offset(int index, unsigned long val)
6804 int n;
6805 unsigned long *tab;
6807 if (index >= nb_got_offsets) {
6808 /* find immediately bigger power of 2 and reallocate array */
6809 n = 1;
6810 while (index >= n)
6811 n *= 2;
6812 tab = realloc(got_offsets, n * sizeof(unsigned long));
6813 if (!tab)
6814 error("memory full");
6815 got_offsets = tab;
6816 memset(got_offsets + nb_got_offsets, 0,
6817 (n - nb_got_offsets) * sizeof(unsigned long));
6818 nb_got_offsets = n;
6820 got_offsets[index] = val;
6823 /* XXX: suppress that */
6824 static void put32(unsigned char *p, unsigned int val)
6826 p[0] = val;
6827 p[1] = val >> 8;
6828 p[2] = val >> 16;
6829 p[3] = val >> 24;
6832 static void build_got(void)
6834 unsigned char *ptr;
6836 /* if no got, then create it */
6837 got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6838 got->sh_entsize = 4;
6839 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
6840 got->sh_num, "_GLOBAL_OFFSET_TABLE_");
6841 ptr = section_ptr_add(got, 3 * sizeof(int));
6842 /* keep space for _DYNAMIC pointer, if present */
6843 put32(ptr, 0);
6844 /* two dummy got entries */
6845 put32(ptr + 4, 0);
6846 put32(ptr + 8, 0);
6849 /* put a got entry corresponding to a symbol in symtab_section. 'size'
6850 and 'info' can be modifed if more precise info comes from the DLL */
6851 static void put_got_entry(int reloc_type, unsigned long size, int info,
6852 int sym_index)
6854 int index;
6855 const char *name;
6856 Elf32_Sym *sym;
6857 unsigned long offset;
6858 int *ptr;
6860 if (!got)
6861 build_got();
6863 /* if a got entry already exists for that symbol, no need to add one */
6864 if (sym_index < nb_got_offsets &&
6865 got_offsets[sym_index] != 0)
6866 return;
6868 put_got_offset(sym_index, got->data_offset);
6870 if (dynsym) {
6871 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6872 name = symtab_section->link->data + sym->st_name;
6873 offset = sym->st_value;
6874 /* NOTE: we put temporarily the got offset */
6875 if (reloc_type == R_386_JMP_SLOT) {
6876 nb_plt_entries++;
6877 offset = got->data_offset;
6879 index = put_elf_sym(dynsym, offset,
6880 size, info, 0, sym->st_shndx, name);
6881 /* put a got entry */
6882 put_elf_reloc(dynsym, got,
6883 got->data_offset,
6884 reloc_type, index);
6886 ptr = section_ptr_add(got, sizeof(int));
6887 *ptr = 0;
6890 /* build GOT and PLT entries */
6891 static void build_got_entries(void)
6893 Section *s, *symtab;
6894 Elf32_Rel *rel, *rel_end;
6895 Elf32_Sym *sym;
6896 int i, type, reloc_type, sym_index;
6898 for(i = 1; i < nb_sections; i++) {
6899 s = sections[i];
6900 if (s->sh_type != SHT_REL)
6901 continue;
6902 /* no need to handle got relocations */
6903 if (s->link != symtab_section)
6904 continue;
6905 symtab = s->link;
6906 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
6907 for(rel = (Elf32_Rel *)s->data;
6908 rel < rel_end;
6909 rel++) {
6910 type = ELF32_R_TYPE(rel->r_info);
6911 switch(type) {
6912 case R_386_GOT32:
6913 case R_386_GOTOFF:
6914 case R_386_GOTPC:
6915 case R_386_PLT32:
6916 if (!got)
6917 build_got();
6918 if (type == R_386_GOT32 || type == R_386_PLT32) {
6919 sym_index = ELF32_R_SYM(rel->r_info);
6920 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6921 /* look at the symbol got offset. If none, then add one */
6922 if (type == R_386_GOT32)
6923 reloc_type = R_386_GLOB_DAT;
6924 else
6925 reloc_type = R_386_JMP_SLOT;
6926 put_got_entry(reloc_type, sym->st_size, sym->st_info,
6927 sym_index);
6929 break;
6930 default:
6931 break;
6937 static Section *new_section_hash(const char *name, int sh_flags,
6938 int nb_buckets, Section *symtab)
6940 Section *hash;
6941 hash = new_section(name, SHT_HASH, sh_flags);
6942 ((int *)hash->data)[0] = nb_buckets;
6943 ((int *)hash->data)[1] = 1;
6944 hash->sh_entsize = sizeof(int);
6945 section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
6946 symtab->hash = hash;
6947 hash->link = symtab;
6948 return hash;
6951 /* put dynamic tag */
6952 static void put_dt(Section *dynamic, int dt, unsigned long val)
6954 Elf32_Dyn *dyn;
6955 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
6956 dyn->d_tag = dt;
6957 dyn->d_un.d_val = val;
6960 /* add tcc runtime libraries */
6961 static void tcc_add_runtime(TCCState *s1)
6963 char buf[1024];
6964 unsigned long *ptr;
6966 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
6967 tcc_add_file(s1, buf);
6968 #ifdef CONFIG_TCC_BCHECK
6969 if (do_bounds_check) {
6970 /* XXX: add an object file to do that */
6971 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
6972 *ptr = 0;
6973 add_elf_sym(symtab_section, 0, 0,
6974 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
6975 bounds_section->sh_num, "__bounds_start");
6976 add_elf_sym(symtab_section, (long)&rt_error, 0,
6977 ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
6978 SHN_ABS, "rt_error");
6979 /* add bound check code */
6980 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
6981 tcc_add_file(s1, buf);
6983 #endif
6984 /* add libc if not memory output */
6985 if (s1->output_type != TCC_OUTPUT_MEMORY) {
6986 tcc_add_library(s1, "c");
6987 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
6989 /* add various standard linker symbols */
6990 add_elf_sym(symtab_section,
6991 text_section->data_offset, 0,
6992 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
6993 text_section->sh_num, "_etext");
6994 add_elf_sym(symtab_section,
6995 data_section->data_offset, 0,
6996 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
6997 data_section->sh_num, "_edata");
6998 add_elf_sym(symtab_section,
6999 bss_section->data_offset, 0,
7000 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7001 bss_section->sh_num, "_end");
7004 /* add dynamic sections so that the executable is dynamically linked */
7005 static char elf_interp[] = "/lib/ld-linux.so.2";
7007 #define ELF_START_ADDR 0x08048000
7008 #define ELF_PAGE_SIZE 0x1000
7010 /* output an ELF file */
7011 /* XXX: handle realloc'ed sections (instead of mmaping them) */
7012 /* XXX: suppress unneeded sections */
7013 int tcc_output_file(TCCState *s1, const char *filename)
7015 Elf32_Ehdr ehdr;
7016 FILE *f;
7017 int fd, mode;
7018 int *section_order;
7019 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
7020 unsigned long addr;
7021 Section *strsec, *s;
7022 Elf32_Shdr shdr, *sh;
7023 Elf32_Phdr *phdr, *ph;
7024 Section *interp, *plt, *dynamic, *dynstr, *hash;
7025 unsigned long saved_dynamic_data_offset;
7026 Elf32_Sym *sym;
7027 int type, file_type;
7028 unsigned long rel_addr, rel_size;
7030 file_type = s1->output_type;
7032 if (file_type != TCC_OUTPUT_OBJ)
7033 tcc_add_runtime(s1);
7035 interp = NULL;
7036 dynamic = NULL;
7037 dynsym = NULL;
7038 got = NULL;
7039 nb_plt_entries = 0;
7040 plt = NULL; /* avoid warning */
7041 hash = NULL; /* avoid warning */
7042 dynstr = NULL; /* avoid warning */
7043 saved_dynamic_data_offset = 0; /* avoid warning */
7045 if (file_type != TCC_OUTPUT_OBJ) {
7047 relocate_common_syms();
7049 if (!static_link) {
7050 const char *name;
7051 int sym_index, index;
7052 Elf32_Sym *esym, *sym_end;
7054 if (file_type == TCC_OUTPUT_EXE) {
7055 char *ptr;
7056 /* add interpreter section only if executable */
7057 interp = new_section(".interp", SHT_PROGBITS, SHF_ALLOC);
7058 interp->sh_addralign = 1;
7059 ptr = section_ptr_add(interp, sizeof(elf_interp));
7060 strcpy(ptr, elf_interp);
7063 /* add dynamic symbol table */
7064 dynsym = new_section(".dynsym", SHT_DYNSYM, SHF_ALLOC);
7065 dynsym->sh_entsize = sizeof(Elf32_Sym);
7066 dynstr = new_section(".dynstr", SHT_STRTAB, SHF_ALLOC);
7067 put_elf_str(dynstr, "");
7068 dynsym->link = dynstr;
7069 put_elf_sym(dynsym, 0, 0, 0, 0, 0, NULL);
7071 /* hash table */
7072 hash = new_section_hash(".hash", SHF_ALLOC,
7073 ELF_DYNSYM_HASH_SIZE, dynsym);
7075 /* add dynamic section */
7076 dynamic = new_section(".dynamic", SHT_DYNAMIC,
7077 SHF_ALLOC | SHF_WRITE);
7078 dynamic->link = dynstr;
7079 dynamic->sh_entsize = sizeof(Elf32_Dyn);
7081 /* add PLT */
7082 plt = new_section(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7083 plt->sh_entsize = 4;
7085 /* scan for undefined symbols and see if they are in the
7086 dynamic symbols. If a symbol STT_FUNC is found, then we
7087 add it in the PLT. If a symbol STT_OBJECT is found, we
7088 add it in the .bss section with a suitable relocation */
7089 sym_end = (Elf32_Sym *)(symtab_section->data +
7090 symtab_section->data_offset);
7091 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7092 sym < sym_end;
7093 sym++) {
7094 if (sym->st_shndx == SHN_UNDEF) {
7095 name = symtab_section->link->data + sym->st_name;
7096 sym_index = find_elf_sym(dynsymtab_section, name);
7097 if (sym_index) {
7098 esym = &((Elf32_Sym *)dynsymtab_section->data)[sym_index];
7099 type = ELF32_ST_TYPE(esym->st_info);
7100 if (type == STT_FUNC) {
7101 put_got_entry(R_386_JMP_SLOT, esym->st_size,
7102 esym->st_info,
7103 sym - (Elf32_Sym *)symtab_section->data);
7104 } else if (type == STT_OBJECT) {
7105 unsigned long offset;
7106 offset = bss_section->data_offset;
7107 /* XXX: which alignment ? */
7108 offset = (offset + 8 - 1) & -8;
7109 index = put_elf_sym(dynsym, offset, esym->st_size,
7110 esym->st_info, 0,
7111 bss_section->sh_num, name);
7112 put_elf_reloc(dynsym, bss_section,
7113 offset, R_386_COPY, index);
7114 offset += esym->st_size;
7115 bss_section->data_offset = offset;
7117 } else {
7118 /* STT_NOTYPE or STB_WEAK undefined symbols
7119 are accepted */
7120 /* XXX: STT_NOTYPE is only used to exclude the
7121 unreferenced '_fp_hw' symbol. need a better
7122 solution */
7123 if (ELF32_ST_TYPE(sym->st_info) == STT_NOTYPE ||
7124 ELF32_ST_BIND(sym->st_info) == STB_WEAK) {
7125 } else {
7126 error("undefined symbol '%s'", name);
7132 /* now look at unresolved dynamic symbols and export
7133 corresponding symbol */
7134 sym_end = (Elf32_Sym *)(dynsymtab_section->data +
7135 dynsymtab_section->data_offset);
7136 for(sym = (Elf32_Sym *)dynsymtab_section->data + 1;
7137 sym < sym_end;
7138 sym++) {
7139 if (sym->st_shndx == SHN_UNDEF) {
7140 name = dynsymtab_section->link->data + sym->st_name;
7141 sym_index = find_elf_sym(symtab_section, name);
7142 if (sym_index) {
7143 } else {
7144 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK) {
7145 /* weak symbols can stay undefined */
7146 } else {
7147 warning("undefined dynamic symbol '%s'", name);
7153 build_got_entries();
7155 /* update PLT/GOT sizes so that we can allocate their space */
7156 plt->data_offset += 16 * (nb_plt_entries + 1);
7158 /* add a list of needed dlls */
7159 for(i = 0; i < nb_loaded_dlls; i++) {
7160 DLLReference *dllref = loaded_dlls[i];
7161 if (dllref->level == 0)
7162 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
7165 /* add necessary space for other entries */
7166 saved_dynamic_data_offset = dynamic->data_offset;
7167 dynamic->data_offset += 8 * 9;
7168 } else {
7169 /* still need to build got entries in case of static link */
7170 build_got_entries();
7174 memset(&ehdr, 0, sizeof(ehdr));
7176 /* we add a section for symbols */
7177 strsec = new_section(".shstrtab", SHT_STRTAB, 0);
7178 put_elf_str(strsec, "");
7180 /* compute number of sections */
7181 shnum = nb_sections;
7183 /* this array is used to reorder sections in the output file */
7184 section_order = malloc(sizeof(int) * shnum);
7185 if (!section_order)
7186 error("memory full");
7187 section_order[0] = 0;
7188 sh_order_index = 1;
7190 /* compute number of program headers */
7191 switch(file_type) {
7192 default:
7193 case TCC_OUTPUT_OBJ:
7194 phnum = 0;
7195 break;
7196 case TCC_OUTPUT_EXE:
7197 if (!static_link)
7198 phnum = 4;
7199 else
7200 phnum = 2;
7201 break;
7202 case TCC_OUTPUT_DLL:
7203 phnum = 3;
7204 break;
7207 /* allocate strings for section names */
7208 for(i = 1; i < nb_sections; i++) {
7209 s = sections[i];
7210 s->sh_name = put_elf_str(strsec, s->name);
7211 s->sh_size = s->data_offset;
7214 /* allocate program segment headers */
7215 phdr = malloc(phnum * sizeof(Elf32_Phdr));
7216 if (!phdr)
7217 error("memory full");
7218 memset(phdr, 0, phnum * sizeof(Elf32_Phdr));
7220 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
7221 if (phnum > 0) {
7222 /* compute section to program header mapping */
7223 if (file_type == TCC_OUTPUT_DLL)
7224 addr = 0;
7225 else
7226 addr = ELF_START_ADDR;
7228 /* dynamic relocation table information, for .dynamic section */
7229 rel_size = 0;
7230 rel_addr = 0;
7232 /* compute address after headers */
7233 addr += (file_offset & (ELF_PAGE_SIZE - 1));
7235 /* leave one program header for the program interpreter */
7236 ph = &phdr[0];
7237 if (interp)
7238 ph++;
7240 for(j = 0; j < 2; j++) {
7241 ph->p_type = PT_LOAD;
7242 if (j == 0)
7243 ph->p_flags = PF_R | PF_X;
7244 else
7245 ph->p_flags = PF_R | PF_W;
7246 ph->p_align = ELF_PAGE_SIZE;
7248 /* we do the following ordering: interp, symbol tables,
7249 relocations, progbits, nobits */
7250 /* XXX: do faster and simpler sorting */
7251 for(k = 0; k < 5; k++) {
7252 for(i = 1; i < nb_sections; i++) {
7253 s = sections[i];
7254 /* compute if section should be included */
7255 if (j == 0) {
7256 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
7257 SHF_ALLOC)
7258 continue;
7259 } else {
7260 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
7261 (SHF_ALLOC | SHF_WRITE))
7262 continue;
7264 if (s == interp) {
7265 if (k != 0)
7266 continue;
7267 } else if (s->sh_type == SHT_DYNSYM ||
7268 s->sh_type == SHT_STRTAB ||
7269 s->sh_type == SHT_HASH) {
7270 if (k != 1)
7271 continue;
7272 } else if (s->sh_type == SHT_REL) {
7273 if (k != 2)
7274 continue;
7275 } else if (s->sh_type == SHT_NOBITS) {
7276 if (k != 4)
7277 continue;
7278 } else {
7279 if (k != 3)
7280 continue;
7282 section_order[sh_order_index++] = i;
7284 /* section matches: we align it and add its size */
7285 tmp = file_offset;
7286 file_offset = (file_offset + s->sh_addralign - 1) &
7287 ~(s->sh_addralign - 1);
7288 s->sh_offset = file_offset;
7289 addr += file_offset - tmp;
7290 s->sh_addr = addr;
7292 /* update program header infos */
7293 if (ph->p_offset == 0) {
7294 ph->p_offset = file_offset;
7295 ph->p_vaddr = addr;
7296 ph->p_paddr = ph->p_vaddr;
7298 /* update dynamic relocation infos */
7299 if (s->sh_type == SHT_REL) {
7300 if (rel_size == 0)
7301 rel_addr = addr;
7302 rel_size += s->sh_size;
7304 addr += s->sh_size;
7305 if (s->sh_type != SHT_NOBITS)
7306 file_offset += s->sh_size;
7309 ph->p_filesz = file_offset - ph->p_offset;
7310 ph->p_memsz = addr - ph->p_vaddr;
7311 ph++;
7314 /* if interpreter, then add corresponing program header */
7315 if (interp) {
7316 ph = &phdr[0];
7318 ph->p_type = PT_INTERP;
7319 ph->p_offset = interp->sh_offset;
7320 ph->p_vaddr = interp->sh_addr;
7321 ph->p_paddr = ph->p_vaddr;
7322 ph->p_filesz = interp->sh_size;
7323 ph->p_memsz = interp->sh_size;
7324 ph->p_flags = PF_R;
7325 ph->p_align = interp->sh_addralign;
7328 /* if dynamic section, then add corresponing program header */
7329 if (dynamic) {
7330 int plt_offset;
7331 unsigned char *p;
7332 Elf32_Sym *sym_end;
7334 ph = &phdr[phnum - 1];
7336 ph->p_type = PT_DYNAMIC;
7337 ph->p_offset = dynamic->sh_offset;
7338 ph->p_vaddr = dynamic->sh_addr;
7339 ph->p_paddr = ph->p_vaddr;
7340 ph->p_filesz = dynamic->sh_size;
7341 ph->p_memsz = dynamic->sh_size;
7342 ph->p_flags = PF_R | PF_W;
7343 ph->p_align = dynamic->sh_addralign;
7345 /* put GOT dynamic section address */
7346 put32(got->data, dynamic->sh_addr);
7348 /* compute the PLT */
7349 plt->data_offset = 0;
7351 /* first plt entry */
7352 p = section_ptr_add(plt, 16);
7353 p[0] = 0xff; /* pushl got + 4 */
7354 p[1] = 0x35;
7355 put32(p + 2, got->sh_addr + 4);
7356 p[6] = 0xff; /* jmp *(got + 8) */
7357 p[7] = 0x25;
7358 put32(p + 8, got->sh_addr + 8);
7360 /* relocation symbols in .dynsym and build PLT. */
7361 plt_offset = 0;
7362 sym_end = (Elf32_Sym *)(dynsym->data + dynsym->data_offset);
7363 for(sym = (Elf32_Sym *)dynsym->data + 1;
7364 sym < sym_end;
7365 sym++) {
7366 type = ELF32_ST_TYPE(sym->st_info);
7367 if (sym->st_shndx == SHN_UNDEF) {
7368 if (type == STT_FUNC) {
7369 /* one more entry in PLT */
7370 p = section_ptr_add(plt, 16);
7371 p[0] = 0xff; /* jmp *(got + x) */
7372 p[1] = 0x25;
7373 put32(p + 2, got->sh_addr + sym->st_value);
7374 p[6] = 0x68; /* push $xxx */
7375 put32(p + 7, plt_offset);
7376 p[11] = 0xe9; /* jmp plt_start */
7377 put32(p + 12, -(plt->data_offset));
7379 /* patch symbol value to point to plt */
7380 sym->st_value = plt->sh_addr + p - plt->data;
7382 plt_offset += 8;
7384 } else if (sym->st_shndx < SHN_LORESERVE) {
7385 /* do symbol relocation */
7386 sym->st_value += sections[sym->st_shndx]->sh_addr;
7389 /* put dynamic section entries */
7391 dynamic->data_offset = saved_dynamic_data_offset;
7392 put_dt(dynamic, DT_HASH, hash->sh_addr);
7393 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
7394 put_dt(dynamic, DT_SYMTAB, dynsym->sh_addr);
7395 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
7396 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
7397 put_dt(dynamic, DT_REL, rel_addr);
7398 put_dt(dynamic, DT_RELSZ, rel_size);
7399 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
7400 put_dt(dynamic, DT_NULL, 0);
7403 ehdr.e_phentsize = sizeof(Elf32_Phdr);
7404 ehdr.e_phnum = phnum;
7405 ehdr.e_phoff = sizeof(Elf32_Ehdr);
7408 /* all other sections come after */
7409 for(i = 1; i < nb_sections; i++) {
7410 s = sections[i];
7411 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
7412 continue;
7413 section_order[sh_order_index++] = i;
7415 file_offset = (file_offset + s->sh_addralign - 1) &
7416 ~(s->sh_addralign - 1);
7417 s->sh_offset = file_offset;
7418 if (s->sh_type != SHT_NOBITS)
7419 file_offset += s->sh_size;
7422 /* if building executable or DLL, then relocate each section
7423 except the GOT which is already relocated */
7424 if (file_type != TCC_OUTPUT_OBJ) {
7425 relocate_syms(0);
7427 /* relocate sections */
7428 /* XXX: ignore sections with allocated relocations ? */
7429 for(i = 1; i < nb_sections; i++) {
7430 s = sections[i];
7431 if (s->reloc && s != got)
7432 relocate_section(s);
7435 /* relocate relocation entries if the relocation tables are
7436 allocated in the executable */
7437 for(i = 1; i < nb_sections; i++) {
7438 s = sections[i];
7439 if ((s->sh_flags & SHF_ALLOC) &&
7440 s->sh_type == SHT_REL) {
7441 relocate_rel(s);
7445 /* get entry point address */
7446 ehdr.e_entry = get_elf_sym_val("_start");
7449 sort_syms(symtab_section);
7451 /* align to 4 */
7452 file_offset = (file_offset + 3) & -4;
7454 /* fill header */
7455 ehdr.e_ident[0] = ELFMAG0;
7456 ehdr.e_ident[1] = ELFMAG1;
7457 ehdr.e_ident[2] = ELFMAG2;
7458 ehdr.e_ident[3] = ELFMAG3;
7459 ehdr.e_ident[4] = ELFCLASS32;
7460 ehdr.e_ident[5] = ELFDATA2LSB;
7461 ehdr.e_ident[6] = EV_CURRENT;
7462 switch(file_type) {
7463 default:
7464 case TCC_OUTPUT_EXE:
7465 ehdr.e_type = ET_EXEC;
7466 break;
7467 case TCC_OUTPUT_DLL:
7468 ehdr.e_type = ET_DYN;
7469 break;
7470 case TCC_OUTPUT_OBJ:
7471 ehdr.e_type = ET_REL;
7472 break;
7474 ehdr.e_machine = EM_386;
7475 ehdr.e_version = EV_CURRENT;
7476 ehdr.e_shoff = file_offset;
7477 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
7478 ehdr.e_shentsize = sizeof(Elf32_Shdr);
7479 ehdr.e_shnum = shnum;
7480 ehdr.e_shstrndx = shnum - 1;
7482 /* write elf file */
7483 if (file_type == TCC_OUTPUT_OBJ)
7484 mode = 0666;
7485 else
7486 mode = 0777;
7487 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
7488 if (fd < 0)
7489 error("could not write '%s'", filename);
7491 f = fdopen(fd, "w");
7492 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
7493 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
7494 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
7495 for(i=1;i<nb_sections;i++) {
7496 s = sections[section_order[i]];
7497 if (s->sh_type != SHT_NOBITS) {
7498 while (offset < s->sh_offset) {
7499 fputc(0, f);
7500 offset++;
7502 size = s->data_offset;
7503 fwrite(s->data, 1, size, f);
7504 offset += size;
7507 while (offset < ehdr.e_shoff) {
7508 fputc(0, f);
7509 offset++;
7512 /* output section headers */
7513 for(i=0;i<nb_sections;i++) {
7514 sh = &shdr;
7515 memset(sh, 0, sizeof(Elf32_Shdr));
7516 s = sections[i];
7517 if (s) {
7518 sh->sh_name = s->sh_name;
7519 sh->sh_type = s->sh_type;
7520 sh->sh_flags = s->sh_flags;
7521 sh->sh_entsize = s->sh_entsize;
7522 sh->sh_info = s->sh_info;
7523 if (s->link)
7524 sh->sh_link = s->link->sh_num;
7525 sh->sh_addralign = s->sh_addralign;
7526 sh->sh_addr = s->sh_addr;
7527 sh->sh_offset = s->sh_offset;
7528 sh->sh_size = s->sh_size;
7530 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
7532 fclose(f);
7534 free(section_order);
7535 free(phdr);
7536 return 0;
7539 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
7541 void *data;
7543 data = malloc(size);
7544 if (!data)
7545 error("memory full");
7546 lseek(fd, file_offset, SEEK_SET);
7547 read(fd, data, size);
7548 return data;
7551 typedef struct SectionMergeInfo {
7552 Section *s; /* corresponding existing section */
7553 unsigned long offset; /* offset of the new section in the existing section */
7554 int new_section; /* true if section 's' was added */
7555 } SectionMergeInfo;
7557 /* load an object file and merge it with current files */
7558 /* XXX: handle correctly stab (debug) info */
7559 static int tcc_load_object_file(TCCState *s1,
7560 int fd, unsigned long file_offset)
7562 Elf32_Ehdr ehdr;
7563 Elf32_Shdr *shdr, *sh;
7564 int size, i, j, offset, offseti, nb_syms, sym_index;
7565 unsigned char *strsec, *strtab;
7566 int *old_to_new_syms;
7567 char *sh_name, *name;
7568 SectionMergeInfo *sm_table, *sm;
7569 Elf32_Sym *sym, *symtab;
7570 Elf32_Rel *rel, *rel_end;
7571 Section *s;
7573 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
7574 goto fail;
7575 if (ehdr.e_ident[0] != ELFMAG0 ||
7576 ehdr.e_ident[1] != ELFMAG1 ||
7577 ehdr.e_ident[2] != ELFMAG2 ||
7578 ehdr.e_ident[3] != ELFMAG3)
7579 goto fail;
7580 /* test if object file */
7581 if (ehdr.e_type != ET_REL)
7582 goto fail;
7583 /* test CPU specific stuff */
7584 if (ehdr.e_ident[5] != ELFDATA2LSB ||
7585 ehdr.e_machine != EM_386) {
7586 fail:
7587 error("invalid object file");
7589 /* read sections */
7590 shdr = load_data(fd, file_offset + ehdr.e_shoff,
7591 sizeof(Elf32_Shdr) * ehdr.e_shnum);
7592 sm_table = malloc(sizeof(SectionMergeInfo) * ehdr.e_shnum);
7593 if (!sm_table)
7594 error("memory full");
7595 memset(sm_table, 0, sizeof(SectionMergeInfo) * ehdr.e_shnum);
7597 /* load section names */
7598 sh = &shdr[ehdr.e_shstrndx];
7599 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
7601 /* load symtab and strtab */
7602 symtab = NULL;
7603 strtab = NULL;
7604 nb_syms = 0;
7605 for(i = 1; i < ehdr.e_shnum; i++) {
7606 sh = &shdr[i];
7607 if (sh->sh_type == SHT_SYMTAB) {
7608 if (symtab)
7609 error("object must contain only one symtab");
7610 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
7611 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
7612 sm_table[i].s = symtab_section;
7614 /* now load strtab */
7615 sh = &shdr[sh->sh_link];
7616 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
7620 /* now examine each section and try to merge its content with the
7621 ones in memory */
7622 for(i = 1; i < ehdr.e_shnum; i++) {
7623 /* no need to examine section name strtab */
7624 if (i == ehdr.e_shstrndx)
7625 continue;
7626 sh = &shdr[i];
7627 sh_name = strsec + sh->sh_name;
7628 /* ignore sections types we do not handle */
7629 if (sh->sh_type != SHT_PROGBITS &&
7630 sh->sh_type != SHT_REL &&
7631 sh->sh_type != SHT_NOBITS)
7632 continue;
7633 if (sh->sh_addralign < 1)
7634 sh->sh_addralign = 1;
7635 /* find corresponding section, if any */
7636 for(j = 1; j < nb_sections;j++) {
7637 s = sections[j];
7638 if (!strcmp(s->name, sh_name))
7639 goto found;
7641 /* not found: create new section */
7642 s = new_section(sh_name, sh->sh_type, sh->sh_flags);
7643 /* take as much info as possible from the section. sh_link and
7644 sh_info will be updated later */
7645 s->sh_addralign = sh->sh_addralign;
7646 s->sh_entsize = sh->sh_entsize;
7647 sm_table[i].new_section = 1;
7648 found:
7649 if (sh->sh_type != s->sh_type)
7650 goto fail;
7652 /* align start of section */
7653 offset = s->data_offset;
7654 size = sh->sh_addralign - 1;
7655 offset = (offset + size) & ~size;
7656 if (sh->sh_addralign > s->sh_addralign)
7657 s->sh_addralign = sh->sh_addralign;
7658 s->data_offset = offset;
7659 sm_table[i].offset = offset;
7660 sm_table[i].s = s;
7661 /* concatenate sections */
7662 size = sh->sh_size;
7663 if (sh->sh_type != SHT_NOBITS) {
7664 unsigned char *ptr;
7665 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
7666 ptr = section_ptr(s, size);
7667 read(fd, ptr, size);
7669 s->data_offset += size;
7672 /* second short pass to update sh_link and sh_info fields of new
7673 sections */
7674 sm = sm_table;
7675 for(i = 1; i < ehdr.e_shnum; i++) {
7676 s = sm_table[i].s;
7677 if (!s || !sm_table[i].new_section)
7678 continue;
7679 sh = &shdr[i];
7680 if (sh->sh_link > 0)
7681 s->link = sm_table[sh->sh_link].s;
7682 if (sh->sh_type == SHT_REL) {
7683 s->sh_info = sm_table[sh->sh_info].s->sh_num;
7684 /* update backward link */
7685 sections[s->sh_info]->reloc = s;
7689 /* resolve symbols */
7690 old_to_new_syms = malloc(nb_syms * sizeof(int));
7691 if (!old_to_new_syms)
7692 error("memory full");
7693 memset(old_to_new_syms, 0, nb_syms * sizeof(int));
7694 sym = symtab + 1;
7695 for(i = 1; i < nb_syms; i++, sym++) {
7696 if (sym->st_shndx != SHN_UNDEF &&
7697 sym->st_shndx < SHN_LORESERVE) {
7698 sm = &sm_table[sym->st_shndx];
7699 /* if no corresponding section added, no need to add symbol */
7700 if (!sm->s)
7701 continue;
7702 /* convert section number */
7703 sym->st_shndx = sm->s->sh_num;
7704 /* offset value */
7705 sym->st_value += sm->offset;
7707 /* add symbol */
7708 name = strtab + sym->st_name;
7709 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
7710 sym->st_info, sym->st_shndx, name);
7711 old_to_new_syms[i] = sym_index;
7714 /* third pass to patch relocation entries */
7715 for(i = 1; i < ehdr.e_shnum; i++) {
7716 s = sm_table[i].s;
7717 if (!s)
7718 continue;
7719 sh = &shdr[i];
7720 offset = sm_table[i].offset;
7721 switch(s->sh_type) {
7722 case SHT_REL:
7723 /* take relocation offset information */
7724 offseti = sm_table[sh->sh_info].offset;
7725 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
7726 for(rel = (Elf32_Rel *)(s->data + offset);
7727 rel < rel_end;
7728 rel++) {
7729 int type;
7730 unsigned sym_index;
7731 /* convert symbol index */
7732 type = ELF32_R_TYPE(rel->r_info);
7733 sym_index = ELF32_R_SYM(rel->r_info);
7734 /* NOTE: only one symtab assumed */
7735 if (sym_index >= nb_syms)
7736 goto invalid_reloc;
7737 sym_index = old_to_new_syms[sym_index];
7738 if (!sym_index) {
7739 invalid_reloc:
7740 error("Invalid relocation entry");
7742 rel->r_info = ELF32_R_INFO(sym_index, type);
7743 /* offset the relocation offset */
7744 rel->r_offset += offseti;
7746 break;
7747 default:
7748 break;
7751 free(symtab);
7752 free(strtab);
7753 free(old_to_new_syms);
7754 free(sm_table);
7755 free(shdr);
7756 return 0;
7759 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7761 typedef struct ArchiveHeader {
7762 char ar_name[16]; /* name of this member */
7763 char ar_date[12]; /* file mtime */
7764 char ar_uid[6]; /* owner uid; printed as decimal */
7765 char ar_gid[6]; /* owner gid; printed as decimal */
7766 char ar_mode[8]; /* file mode, printed as octal */
7767 char ar_size[10]; /* file size, printed as decimal */
7768 char ar_fmag[2]; /* should contain ARFMAG */
7769 } ArchiveHeader;
7771 /* load a '.a' file */
7772 static int tcc_load_archive(TCCState *s1, int fd)
7774 ArchiveHeader hdr;
7775 char ar_size[11];
7776 char ar_name[17];
7777 char magic[8];
7778 int size, len, i;
7779 unsigned long file_offset;
7781 /* skip magic which was already checked */
7782 read(fd, magic, sizeof(magic));
7784 for(;;) {
7785 len = read(fd, &hdr, sizeof(hdr));
7786 if (len == 0)
7787 break;
7788 if (len != sizeof(hdr))
7789 error("invalid archive");
7790 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
7791 ar_size[sizeof(hdr.ar_size)] = '\0';
7792 size = strtol(ar_size, NULL, 0);
7793 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
7794 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
7795 if (ar_name[i] != ' ')
7796 break;
7798 ar_name[i + 1] = '\0';
7799 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7800 file_offset = lseek(fd, 0, SEEK_CUR);
7801 if (!strcmp(ar_name, "/") ||
7802 !strcmp(ar_name, "//") ||
7803 !strcmp(ar_name, "__.SYMDEF") ||
7804 !strcmp(ar_name, "__.SYMDEF/") ||
7805 !strcmp(ar_name, "ARFILENAMES/")) {
7806 /* skip symbol table or archive names */
7807 } else {
7808 tcc_load_object_file(s1, fd, file_offset);
7810 /* align to even */
7811 size = (size + 1) & ~1;
7812 lseek(fd, file_offset + size, SEEK_SET);
7814 return 0;
7817 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
7818 is referenced by the user (so it should be added as DT_NEEDED in
7819 the generated ELF file) */
7820 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
7822 Elf32_Ehdr ehdr;
7823 Elf32_Shdr *shdr, *sh, *sh1;
7824 int i, nb_syms, nb_dts, sym_bind;
7825 Elf32_Sym *sym, *dynsym;
7826 Elf32_Dyn *dt, *dynamic;
7827 unsigned char *dynstr;
7828 const char *name, *soname, *p;
7829 DLLReference *dllref;
7831 read(fd, &ehdr, sizeof(ehdr));
7833 /* test CPU specific stuff */
7834 if (ehdr.e_ident[5] != ELFDATA2LSB ||
7835 ehdr.e_machine != EM_386)
7836 error("bad architecture");
7838 /* read sections */
7839 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
7841 /* load dynamic section and dynamic symbols */
7842 nb_syms = 0;
7843 nb_dts = 0;
7844 dynamic = NULL;
7845 dynsym = NULL; /* avoid warning */
7846 dynstr = NULL; /* avoid warning */
7847 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
7848 switch(sh->sh_type) {
7849 case SHT_DYNAMIC:
7850 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
7851 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
7852 break;
7853 case SHT_DYNSYM:
7854 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
7855 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
7856 sh1 = &shdr[sh->sh_link];
7857 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
7858 break;
7859 default:
7860 break;
7864 /* compute the real library name */
7865 soname = filename;
7866 p = strrchr(soname, '/');
7867 if (p)
7868 soname = p + 1;
7870 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
7871 if (dt->d_tag == DT_SONAME) {
7872 soname = dynstr + dt->d_un.d_val;
7876 /* if the dll is already loaded, do not load it */
7877 for(i = 0; i < nb_loaded_dlls; i++) {
7878 dllref = loaded_dlls[i];
7879 if (!strcmp(soname, dllref->name)) {
7880 /* but update level if needed */
7881 if (level < dllref->level)
7882 dllref->level = level;
7883 goto the_end;
7887 // printf("loading dll '%s'\n", soname);
7889 /* add the dll and its level */
7890 dllref = malloc(sizeof(DLLReference) + strlen(soname));
7891 dllref->level = level;
7892 strcpy(dllref->name, soname);
7893 dynarray_add((void ***)&loaded_dlls, &nb_loaded_dlls, dllref);
7895 /* add dynamic symbols in dynsym_section */
7896 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
7897 sym_bind = ELF32_ST_BIND(sym->st_info);
7898 if (sym_bind == STB_LOCAL)
7899 continue;
7900 name = dynstr + sym->st_name;
7901 add_elf_sym(dynsymtab_section, sym->st_value, sym->st_size,
7902 sym->st_info, sym->st_shndx, name);
7905 /* load all referenced DLLs */
7906 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
7907 switch(dt->d_tag) {
7908 case DT_NEEDED:
7909 name = dynstr + dt->d_un.d_val;
7910 for(i = 0; i < nb_loaded_dlls; i++) {
7911 dllref = loaded_dlls[i];
7912 if (!strcmp(name, dllref->name))
7913 goto already_loaded;
7915 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0)
7916 error("referenced dll '%s' not found", name);
7917 already_loaded:
7918 break;
7921 the_end:
7922 free(shdr);
7923 return 0;
7926 /* return -2 if error and CH_EOF if eof */
7927 static void ld_skipspaces(void)
7929 while (ch == ' ' || ch == '\t' || ch == '\n')
7930 cinp();
7933 static int ld_get_cmd(char *cmd, int cmd_size)
7935 char *q;
7937 ld_skipspaces();
7938 if (ch == CH_EOF)
7939 return -1;
7940 q = cmd;
7941 for(;;) {
7942 if (!((ch >= 'a' && ch <= 'z') ||
7943 (ch >= 'A' && ch <= 'Z') ||
7944 (ch >= '0' && ch <= '9') ||
7945 strchr("/.-_+=$:\\,~?*", ch)))
7946 break;
7947 if ((q - cmd) >= (cmd_size - 1))
7948 return -2;
7949 *q++ = ch;
7950 cinp();
7952 *q = '\0';
7953 return 0;
7956 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
7957 files */
7958 static int tcc_load_ldscript(TCCState *s1)
7960 char cmd[64];
7961 char filename[1024];
7962 int ret;
7964 inp();
7965 cinp();
7966 for(;;) {
7967 ret = ld_get_cmd(cmd, sizeof(cmd));
7968 if (ret == CH_EOF)
7969 return 0;
7970 else if (ret < 0)
7971 return -1;
7972 // printf("cmd='%s'\n", cmd);
7973 if (!strcmp(cmd, "INPUT") ||
7974 !strcmp(cmd, "GROUP")) {
7975 ld_skipspaces();
7976 if (ch != '(')
7977 expect("(");
7978 cinp();
7979 for(;;) {
7980 ld_get_cmd(filename, sizeof(filename));
7981 tcc_add_file(s1, filename);
7982 ld_skipspaces();
7983 if (ch == ',') {
7984 cinp();
7985 } else if (ch == ')') {
7986 cinp();
7987 break;
7988 } else if (ch == CH_EOF) {
7989 error("unexpected end of file");
7992 } else {
7993 return -1;
7996 return 0;
7999 /* print the position in the source file of PC value 'pc' by reading
8000 the stabs debug information */
8001 static void rt_printline(unsigned long wanted_pc)
8003 Stab_Sym *sym, *sym_end;
8004 char func_name[128];
8005 unsigned long func_addr, last_pc, pc;
8006 const char *incl_files[INCLUDE_STACK_SIZE];
8007 int incl_index, len, last_line_num, i;
8008 const char *str, *p;
8010 func_name[0] = '\0';
8011 func_addr = 0;
8012 incl_index = 0;
8013 last_pc = 0xffffffff;
8014 last_line_num = 1;
8015 sym = (Stab_Sym *)stab_section->data + 1;
8016 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8017 while (sym < sym_end) {
8018 switch(sym->n_type) {
8019 /* function start or end */
8020 case N_FUN:
8021 if (sym->n_strx == 0) {
8022 func_name[0] = '\0';
8023 func_addr = 0;
8024 } else {
8025 str = stabstr_section->data + sym->n_strx;
8026 p = strchr(str, ':');
8027 if (!p) {
8028 pstrcpy(func_name, sizeof(func_name), str);
8029 } else {
8030 len = p - str;
8031 if (len > sizeof(func_name) - 1)
8032 len = sizeof(func_name) - 1;
8033 memcpy(func_name, str, len);
8034 func_name[len] = '\0';
8036 func_addr = sym->n_value;
8038 break;
8039 /* line number info */
8040 case N_SLINE:
8041 pc = sym->n_value + func_addr;
8042 if (wanted_pc >= last_pc && wanted_pc < pc)
8043 goto found;
8044 last_pc = pc;
8045 last_line_num = sym->n_desc;
8046 break;
8047 /* include files */
8048 case N_BINCL:
8049 str = stabstr_section->data + sym->n_strx;
8050 add_incl:
8051 if (incl_index < INCLUDE_STACK_SIZE) {
8052 incl_files[incl_index++] = str;
8054 break;
8055 case N_EINCL:
8056 if (incl_index > 1)
8057 incl_index--;
8058 break;
8059 case N_SO:
8060 if (sym->n_strx == 0) {
8061 incl_index = 0; /* end of translation unit */
8062 } else {
8063 str = stabstr_section->data + sym->n_strx;
8064 /* do not add path */
8065 len = strlen(str);
8066 if (len > 0 && str[len - 1] != '/')
8067 goto add_incl;
8069 break;
8071 sym++;
8073 /* did not find line number info: */
8074 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
8075 return;
8076 found:
8077 for(i = 0; i < incl_index - 1; i++)
8078 fprintf(stderr, "In file included from %s\n",
8079 incl_files[i]);
8080 if (incl_index > 0) {
8081 fprintf(stderr, "%s:%d: ",
8082 incl_files[incl_index - 1], last_line_num);
8084 if (func_name[0] != '\0') {
8085 fprintf(stderr, "in function '%s()': ", func_name);
8089 /* emit a run time error at position 'pc' */
8090 void rt_error(unsigned long pc, const char *fmt, ...)
8092 va_list ap;
8093 va_start(ap, fmt);
8095 rt_printline(pc);
8096 vfprintf(stderr, fmt, ap);
8097 fprintf(stderr, "\n");
8098 exit(255);
8099 va_end(ap);
8102 #ifndef WIN32
8103 /* signal handler for fatal errors */
8104 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8106 struct ucontext *uc = puc;
8107 unsigned long pc;
8109 #ifdef __i386__
8110 pc = uc->uc_mcontext.gregs[14];
8111 #else
8112 #error please put the right sigcontext field
8113 #endif
8115 switch(signum) {
8116 case SIGFPE:
8117 switch(siginf->si_code) {
8118 case FPE_INTDIV:
8119 case FPE_FLTDIV:
8120 rt_error(pc, "division by zero");
8121 break;
8122 default:
8123 rt_error(pc, "floating point exception");
8124 break;
8126 break;
8127 case SIGBUS:
8128 case SIGSEGV:
8129 rt_error(pc, "dereferencing invalid pointer");
8130 break;
8131 case SIGILL:
8132 rt_error(pc, "illegal instruction");
8133 break;
8134 case SIGABRT:
8135 rt_error(pc, "abort() called");
8136 break;
8137 default:
8138 rt_error(pc, "caught signal %d", signum);
8139 break;
8141 exit(255);
8143 #endif
8145 /* launch the compiled program with the given arguments */
8146 int tcc_run(TCCState *s1, int argc, char **argv)
8148 Section *s;
8149 int (*prog_main)(int, char **);
8150 void (*bound_init)(void);
8151 int i;
8153 tcc_add_runtime(s1);
8155 relocate_common_syms();
8157 /* compute relocation address : section are relocated in place */
8158 for(i = 1; i < nb_sections; i++) {
8159 s = sections[i];
8160 if (s->sh_flags & SHF_ALLOC)
8161 s->sh_addr = (unsigned long)s->data;
8164 relocate_syms(1);
8166 /* relocate each section */
8167 for(i = 1; i < nb_sections; i++) {
8168 s = sections[i];
8169 if (s->reloc)
8170 relocate_section(s);
8173 prog_main = (void *)get_elf_sym_val("main");
8175 if (do_debug) {
8176 #ifdef WIN32
8177 error("debug mode currently not available for Windows");
8178 #else
8179 struct sigaction sigact;
8180 /* install TCC signal handlers to print debug info on fatal
8181 runtime errors */
8182 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
8183 sigact.sa_sigaction = sig_error;
8184 sigemptyset(&sigact.sa_mask);
8185 sigaction(SIGFPE, &sigact, NULL);
8186 sigaction(SIGILL, &sigact, NULL);
8187 sigaction(SIGSEGV, &sigact, NULL);
8188 sigaction(SIGBUS, &sigact, NULL);
8189 sigaction(SIGABRT, &sigact, NULL);
8190 #endif
8193 #ifdef CONFIG_TCC_BCHECK
8194 if (do_bounds_check) {
8195 /* XXX: use .init section so that it also work in binary ? */
8196 bound_init = (void *)get_elf_sym_val("__bound_init");
8197 bound_init();
8199 #endif
8200 return (*prog_main)(argc, argv);
8203 TCCState *tcc_new(void)
8205 char *p, *r;
8206 TCCState *s;
8208 s = malloc(sizeof(TCCState));
8209 if (!s)
8210 return NULL;
8211 s->output_type = TCC_OUTPUT_MEMORY;
8213 /* default include paths */
8214 tcc_add_include_path(s, "/usr/include");
8215 tcc_add_include_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
8216 tcc_add_include_path(s, "/usr/local/include");
8218 /* add all tokens */
8219 tok_ident = TOK_IDENT;
8220 p = tcc_keywords;
8221 while (*p) {
8222 r = p;
8223 while (*r++);
8224 tok_alloc(p, r - p - 1);
8225 p = r;
8228 /* standard defines */
8229 tcc_define_symbol(s, "__STDC__", NULL);
8230 #if defined(TCC_TARGET_I386)
8231 tcc_define_symbol(s, "__i386__", NULL);
8232 #endif
8233 /* tiny C specific defines */
8234 tcc_define_symbol(s, "__TINYC__", NULL);
8236 /* default library paths */
8237 tcc_add_library_path(s, "/usr/local/lib");
8238 tcc_add_library_path(s, "/usr/lib");
8239 tcc_add_library_path(s, "/lib");
8241 /* no section zero */
8242 dynarray_add((void ***)&sections, &nb_sections, NULL);
8244 /* create standard sections */
8245 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8246 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8247 bss_section = new_section(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8249 /* symbols are always generated for linking stage */
8250 symtab_section = new_section(".symtab", SHT_SYMTAB, 0);
8251 symtab_section->sh_entsize = sizeof(Elf32_Sym);
8252 strtab_section = new_section(".strtab", SHT_STRTAB, 0);
8253 put_elf_str(strtab_section, "");
8254 symtab_section->link = strtab_section;
8255 put_elf_sym(symtab_section, 0, 0, 0, 0, 0, NULL);
8256 new_section_hash(".hashtab", SHF_PRIVATE,
8257 ELF_SYM_HASH_SIZE, symtab_section);
8259 /* private symbol table for dynamic symbols */
8260 dynsymtab_section = new_section(".dynsymtab", SHT_SYMTAB, SHF_PRIVATE);
8261 dynsymtab_section->sh_entsize = sizeof(Elf32_Sym);
8262 dynstrtab_section = new_section(".dynstrtab", SHT_STRTAB, SHF_PRIVATE);
8263 put_elf_str(dynstrtab_section, "");
8264 dynsymtab_section->link = dynstrtab_section;
8265 put_elf_sym(dynsymtab_section, 0, 0, 0, 0, 0, NULL);
8266 new_section_hash(".dynhashtab", SHF_PRIVATE,
8267 ELF_SYM_HASH_SIZE, dynsymtab_section);
8268 return s;
8271 void tcc_delete(TCCState *s)
8273 free(s);
8276 int tcc_add_include_path(TCCState *s, const char *pathname)
8278 char *pathname1;
8280 pathname1 = strdup(pathname);
8281 if (!pathname1)
8282 return -1;
8283 dynarray_add((void ***)&include_paths, &nb_include_paths, pathname1);
8284 return 0;
8287 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags)
8289 const char *ext;
8290 Elf32_Ehdr ehdr;
8291 int fd;
8292 BufferedFile *saved_file;
8294 /* find source file type with extension */
8295 ext = strrchr(filename, '.');
8296 if (ext)
8297 ext++;
8299 /* open the file */
8300 saved_file = file;
8301 file = tcc_open(filename);
8302 if (!file) {
8303 if (flags & AFF_PRINT_ERROR) {
8304 error("file '%s' not found", filename);
8305 } else {
8306 file = saved_file;
8307 return -1;
8311 if (!ext || !strcmp(ext, "c")) {
8312 /* C file assumed */
8313 tcc_compile(s);
8314 } else {
8315 fd = file->fd;
8316 /* assume executable format: auto guess file type */
8317 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
8318 error("could not read header");
8319 lseek(fd, 0, SEEK_SET);
8321 if (ehdr.e_ident[0] == ELFMAG0 &&
8322 ehdr.e_ident[1] == ELFMAG1 &&
8323 ehdr.e_ident[2] == ELFMAG2 &&
8324 ehdr.e_ident[3] == ELFMAG3) {
8325 file->line_num = 0; /* do not display line number if error */
8326 if (ehdr.e_type == ET_REL) {
8327 tcc_load_object_file(s, fd, 0);
8328 } else if (ehdr.e_type == ET_DYN) {
8329 tcc_load_dll(s, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
8330 } else {
8331 error("unrecognized ELF file");
8333 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8334 file->line_num = 0; /* do not display line number if error */
8335 tcc_load_archive(s, fd);
8336 } else {
8337 /* as GNU ld, consider it is an ld script if not recognized */
8338 if (tcc_load_ldscript(s) < 0)
8339 error("unrecognized file type");
8342 tcc_close(file);
8343 file = saved_file;
8344 return 0;
8347 void tcc_add_file(TCCState *s, const char *filename)
8349 tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8352 int tcc_add_library_path(TCCState *s, const char *pathname)
8354 char *pathname1;
8356 pathname1 = strdup(pathname);
8357 if (!pathname1)
8358 return -1;
8359 dynarray_add((void ***)&library_paths, &nb_library_paths, pathname1);
8360 return 0;
8363 /* find and load a dll. Return non zero if not found */
8364 /* XXX: add '-rpath' option support ? */
8365 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8367 char buf[1024];
8368 int i;
8370 for(i = 0; i < nb_library_paths; i++) {
8371 snprintf(buf, sizeof(buf), "%s/%s",
8372 library_paths[i], filename);
8373 if (tcc_add_file_internal(s, buf, flags) == 0)
8374 return 0;
8376 return -1;
8379 /* the library name is the same as the argument of the '-l' option */
8380 int tcc_add_library(TCCState *s, const char *libraryname)
8382 char buf[1024];
8383 int i;
8384 void *h;
8386 /* if we output to memory, then we simply we dlopen(). */
8387 if (s->output_type == TCC_OUTPUT_MEMORY) {
8388 /* Since the libc is already loaded, we don't need to load it again */
8389 if (!strcmp(libraryname, "c"))
8390 return 0;
8391 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8392 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8393 if (!h)
8394 return -1;
8395 return 0;
8398 /* first we look for the dynamic library if not static linking */
8399 if (!static_link) {
8400 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8401 if (tcc_add_dll(s, buf, 0) == 0)
8402 return 0;
8405 /* then we look for the static library */
8406 for(i = 0; i < nb_library_paths; i++) {
8407 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8408 library_paths[i], libraryname);
8409 if (tcc_add_file_internal(s, buf, 0) == 0)
8410 return 0;
8412 return -1;
8415 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8417 add_elf_sym(symtab_section, val, 0,
8418 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8419 SHN_ABS, name);
8420 return 0;
8423 int tcc_set_output_type(TCCState *s, int output_type)
8425 s->output_type = output_type;
8427 /* add libc crt1/crti objects */
8428 if (output_type == TCC_OUTPUT_EXE ||
8429 output_type == TCC_OUTPUT_DLL) {
8430 if (output_type != TCC_OUTPUT_DLL)
8431 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8432 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8434 return 0;
8437 #if !defined(LIBTCC)
8439 void help(void)
8441 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8442 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8443 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
8444 " [--] infile1 [infile2... --] [infile_args...]\n"
8445 "\n"
8446 "General options:\n"
8447 " -c compile only - generate an object file\n"
8448 " -o outfile set output filename\n"
8449 " -- allows multiples input files if no -o option given. Also\n"
8450 " separate input files from runtime arguments\n"
8451 " -Bdir set tcc internal library path\n"
8452 " -bench output compilation statistics\n"
8453 "Preprocessor options:\n"
8454 " -Idir add include path 'dir'\n"
8455 " -Dsym[=val] define 'sym' with value 'val'\n"
8456 " -Usym undefine 'sym'\n"
8457 "C compiler options:\n"
8458 " -g generate runtime debug info\n"
8459 #ifdef CONFIG_TCC_BCHECK
8460 " -b compile with built-in memory and bounds checker (implies -g)\n"
8461 #endif
8462 "Linker options:\n"
8463 " -Ldir add library path 'dir'\n"
8464 " -llib link with dynamic library 'lib'\n"
8465 " -shared generate a shared library (NOT WORKING YET)\n"
8466 " -static static linking\n"
8470 int main(int argc, char **argv)
8472 char *r, *outfile;
8473 int optind, output_type, multiple_files, i;
8474 TCCState *s;
8475 char **libraries;
8476 int nb_libraries;
8478 s = tcc_new();
8479 output_type = TCC_OUTPUT_MEMORY;
8481 optind = 1;
8482 outfile = NULL;
8483 multiple_files = 0;
8484 libraries = NULL;
8485 nb_libraries = 0;
8486 while (1) {
8487 if (optind >= argc) {
8488 show_help:
8489 help();
8490 return 1;
8492 r = argv[optind];
8493 if (r[0] != '-')
8494 break;
8495 optind++;
8496 if (r[1] == '-') {
8497 /* '--' enables multiple files input */
8498 multiple_files = 1;
8499 } else if (r[1] == 'h' || r[1] == '?') {
8500 goto show_help;
8501 } else if (r[1] == 'I') {
8502 if (tcc_add_include_path(s, r + 2) < 0)
8503 error("too many include paths");
8504 } else if (r[1] == 'D') {
8505 char *sym, *value;
8506 sym = r + 2;
8507 value = strchr(sym, '=');
8508 if (value) {
8509 *value = '\0';
8510 value++;
8512 tcc_define_symbol(s, sym, value);
8513 } else if (r[1] == 'U') {
8514 tcc_undefine_symbol(s, r + 2);
8515 } else if (r[1] == 'L') {
8516 tcc_add_library_path(s, r + 2);
8517 } else if (r[1] == 'B') {
8518 /* set tcc utilities path (mainly for tcc development) */
8519 tcc_lib_path = r + 2;
8520 } else if (r[1] == 'l') {
8521 dynarray_add((void ***)&libraries, &nb_libraries, r + 2);
8522 } else if (!strcmp(r + 1, "bench")) {
8523 do_bench = 1;
8524 #ifdef CONFIG_TCC_BCHECK
8525 } else if (r[1] == 'b') {
8526 if (!do_bounds_check) {
8527 do_bounds_check = 1;
8528 /* define symbol */
8529 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8530 /* create bounds sections */
8531 bounds_section = new_section(".bounds",
8532 SHT_PROGBITS, SHF_ALLOC);
8533 lbounds_section = new_section(".lbounds",
8534 SHT_PROGBITS, SHF_ALLOC);
8535 /* debug is implied */
8536 goto debug_opt;
8538 #endif
8539 } else if (r[1] == 'g') {
8540 #ifdef CONFIG_TCC_BCHECK
8541 debug_opt:
8542 #endif
8543 if (!do_debug) {
8544 do_debug = 1;
8546 /* stab symbols */
8547 stab_section = new_section(".stab", SHT_PROGBITS, 0);
8548 stab_section->sh_entsize = sizeof(Stab_Sym);
8549 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
8550 put_elf_str(stabstr_section, "");
8551 stab_section->link = stabstr_section;
8552 /* put first entry */
8553 put_stabs("", 0, 0, 0, 0);
8555 } else
8556 /* the following options are only for testing, so not
8557 documented */
8558 if (r[1] == 'c') {
8559 multiple_files = 1;
8560 output_type = TCC_OUTPUT_OBJ;
8561 } else if (!strcmp(r + 1, "static")) {
8562 static_link = 1;
8563 } else if (!strcmp(r + 1, "shared")) {
8564 output_type = TCC_OUTPUT_DLL;
8565 } else if (r[1] == 'o') {
8566 if (optind >= argc)
8567 goto show_help;
8568 multiple_files = 1;
8569 outfile = argv[optind++];
8570 } else {
8571 error("invalid option -- '%s'", r);
8575 /* if outfile provided without other options, we output an
8576 executable */
8577 if (outfile && output_type == TCC_OUTPUT_MEMORY)
8578 output_type = TCC_OUTPUT_EXE;
8580 /* warning if not supported features */
8581 if (output_type == TCC_OUTPUT_DLL)
8582 warning("dll output is currently not supported");
8583 #ifdef CONFIG_TCC_BCHECK
8584 if (do_bounds_check && output_type != TCC_OUTPUT_MEMORY)
8585 warning("bounds checking is currently only supported for in-memory execution");
8586 #endif
8588 tcc_set_output_type(s, output_type);
8590 tcc_add_file(s, argv[optind]);
8591 if (multiple_files) {
8592 while ((optind + 1) < argc) {
8593 optind++;
8594 r = argv[optind];
8595 if (r[0] == '-') {
8596 if (r[1] != '-')
8597 error("'--' expected");
8598 break;
8600 tcc_add_file(s, r);
8604 /* add specified libraries */
8605 for(i = 0; i < nb_libraries;i++) {
8606 if (tcc_add_library(s, libraries[i]) < 0)
8607 error("cannot find -l%s", libraries[i]);
8610 if (do_bench) {
8611 printf("total: %d idents, %d lines, %d bytes\n",
8612 tok_ident - TOK_IDENT, total_lines, total_bytes);
8615 if (s->output_type != TCC_OUTPUT_MEMORY) {
8616 tcc_output_file(s, outfile);
8617 return 0;
8618 } else {
8619 return tcc_run(s, argc - optind, argv + optind);
8623 #endif