better DLL generation - added size to all ELF symbols - dynamic hash table size
[tinycc.git] / tcc.c
blob9155f234c53b17a687d47091fbe788e88bfe90b4
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
80 /* token symbol management */
81 typedef struct TokenSym {
82 struct TokenSym *hash_next;
83 int tok; /* token number */
84 int len;
85 char str[1];
86 } TokenSym;
88 /* constant value */
89 typedef union CValue {
90 long double ld;
91 double d;
92 float f;
93 int i;
94 unsigned int ui;
95 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
96 long long ll;
97 unsigned long long ull;
98 struct TokenSym *ts;
99 struct Sym *sym;
100 void *ptr;
101 int tab[1];
102 } CValue;
104 /* value on stack */
105 typedef struct SValue {
106 int t; /* type */
107 unsigned short r; /* register + flags */
108 unsigned short r2; /* second register, used for 'long long'
109 type. If not used, set to VT_CONST */
110 CValue c; /* constant, if VT_CONST */
111 } SValue;
113 /* symbol management */
114 typedef struct Sym {
115 int v; /* symbol token */
116 int t; /* associated type */
117 int r; /* associated register */
118 int c; /* associated number */
119 struct Sym *next; /* next related symbol */
120 struct Sym *prev; /* prev symbol in stack */
121 struct Sym *hash_next; /* next symbol in hash table */
122 } Sym;
124 typedef struct SymStack {
125 struct Sym *top;
126 struct Sym *hash[SYM_HASH_SIZE];
127 } SymStack;
129 /* section definition */
130 /* XXX: use directly ELF structure for parameters ? */
131 /* special flag to indicate that the section should not be linked to
132 the other ones */
133 #define SHF_PRIVATE 0x80000000
135 typedef struct Section {
136 unsigned long data_offset; /* current data offset */
137 unsigned char *data; /* section data */
138 int sh_name; /* elf section name (only used during output) */
139 int sh_num; /* elf section number */
140 int sh_type; /* elf section type */
141 int sh_flags; /* elf section flags */
142 int sh_info; /* elf section info */
143 int sh_addralign; /* elf section alignment */
144 int sh_entsize; /* elf entry size */
145 unsigned long sh_size; /* section size (only used during output) */
146 unsigned long sh_addr; /* address at which the section is relocated */
147 unsigned long sh_offset; /* address at which the section is relocated */
148 int nb_hashed_syms; /* used to resize the hash table */
149 struct Section *link; /* link to another section */
150 struct Section *reloc; /* corresponding section for relocation, if any */
151 struct Section *hash; /* hash table for symbols */
152 struct Section *next;
153 char name[64]; /* section name */
154 } Section;
156 typedef struct DLLReference {
157 int level;
158 char name[1];
159 } DLLReference;
161 /* GNUC attribute definition */
162 typedef struct AttributeDef {
163 int aligned;
164 Section *section;
165 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
166 } AttributeDef;
168 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
169 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
170 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
172 /* stored in 'Sym.c' field */
173 #define FUNC_NEW 1 /* ansi function prototype */
174 #define FUNC_OLD 2 /* old function prototype */
175 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
177 /* stored in 'Sym.r' field */
178 #define FUNC_CDECL 0 /* standard c call */
179 #define FUNC_STDCALL 1 /* pascal c call */
181 /* field 'Sym.t' for macros */
182 #define MACRO_OBJ 0 /* object like macro */
183 #define MACRO_FUNC 1 /* function like macro */
185 /* field 'Sym.t' for labels */
186 #define LABEL_FORWARD 1 /* label is forward defined */
188 /* type_decl() types */
189 #define TYPE_ABSTRACT 1 /* type without variable */
190 #define TYPE_DIRECT 2 /* type with variable */
192 #define IO_BUF_SIZE 8192
194 typedef struct BufferedFile {
195 unsigned char *buf_ptr;
196 unsigned char *buf_end;
197 int fd;
198 int line_num; /* current line number - here to simply code */
199 char filename[1024]; /* current filename - here to simplify code */
200 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
201 } BufferedFile;
203 #define CH_EOB 0 /* end of buffer or '\0' char in file */
204 #define CH_EOF (-1) /* end of file */
206 /* parsing state (used to save parser state to reparse part of the
207 source several times) */
208 typedef struct ParseState {
209 int *macro_ptr;
210 int line_num;
211 int tok;
212 CValue tokc;
213 } ParseState;
215 /* used to record tokens */
216 typedef struct TokenString {
217 int *str;
218 int len;
219 int last_line_num;
220 } TokenString;
222 /* parser */
223 struct BufferedFile *file;
224 int ch, ch1, tok, tok1;
225 CValue tokc, tok1c;
226 int return_linefeed; /* if true, line feed is returned as a token */
228 /* sections */
229 Section **sections;
230 int nb_sections; /* number of sections, including first dummy section */
231 Section *text_section, *data_section, *bss_section; /* predefined sections */
232 Section *cur_text_section; /* current section where function code is
233 generated */
234 /* bound check related sections */
235 Section *bounds_section; /* contains global data bound description */
236 Section *lbounds_section; /* contains local data bound description */
237 /* symbol sections */
238 Section *symtab_section, *strtab_section;
239 /* temporary dynamic symbol sections (for dll loading) */
240 Section *dynsymtab_section;
241 /* exported dynamic symbol section */
242 Section *dynsym;
243 /* got handling */
244 Section *got;
245 unsigned long *got_offsets;
246 int nb_got_offsets;
247 int nb_plt_entries;
248 /* give the correspondance from symtab indexes to dynsym indexes */
249 int *symtab_to_dynsym;
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 static void put_extern_sym(Sym *sym, Section *section,
600 unsigned long value, unsigned long size);
601 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
602 static int put_elf_str(Section *s, const char *sym);
603 static int put_elf_sym(Section *s,
604 unsigned long value, unsigned long size,
605 int info, int other, int shndx, const char *name);
606 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
607 int type, int symbol);
608 static void put_stabs(const char *str, int type, int other, int desc,
609 unsigned long value);
610 static void put_stabs_r(const char *str, int type, int other, int desc,
611 unsigned long value, Section *sec, int sym_index);
612 static void put_stabn(int type, int other, int desc, int value);
613 static void put_stabd(int type, int other, int desc);
614 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
616 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
617 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
618 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
620 /* true if float/double/long double type */
621 static inline int is_float(int t)
623 int bt;
624 bt = t & VT_BTYPE;
625 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
628 #ifdef TCC_TARGET_I386
629 #include "i386-gen.c"
630 #endif
631 #ifdef TCC_TARGET_IL
632 #include "il-gen.c"
633 #endif
635 #ifdef CONFIG_TCC_STATIC
637 #define RTLD_LAZY 0x001
638 #define RTLD_NOW 0x002
639 #define RTLD_GLOBAL 0x100
641 /* dummy function for profiling */
642 void *dlopen(const char *filename, int flag)
644 return NULL;
647 const char *dlerror(void)
649 return "error";
652 typedef struct TCCSyms {
653 char *str;
654 void *ptr;
655 } TCCSyms;
657 #define TCCSYM(a) { #a, &a, },
659 /* add the symbol you want here if no dynamic linking is done */
660 static TCCSyms tcc_syms[] = {
661 TCCSYM(printf)
662 TCCSYM(fprintf)
663 TCCSYM(fopen)
664 TCCSYM(fclose)
665 { NULL, NULL },
668 void *dlsym(void *handle, const char *symbol)
670 TCCSyms *p;
671 p = tcc_syms;
672 while (p->str != NULL) {
673 if (!strcmp(p->str, symbol))
674 return p->ptr;
675 p++;
677 return NULL;
680 #endif
682 /********************************************************/
684 /* we use our own 'finite' function to avoid potential problems with
685 non standard math libs */
686 /* XXX: endianness dependant */
687 int ieee_finite(double d)
689 int *p = (int *)&d;
690 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
693 /* copy a string and truncate it. */
694 static char *pstrcpy(char *buf, int buf_size, const char *s)
696 char *q, *q_end;
697 int c;
699 if (buf_size > 0) {
700 q = buf;
701 q_end = buf + buf_size - 1;
702 while (q < q_end) {
703 c = *s++;
704 if (c == '\0')
705 break;
706 *q++ = c;
708 *q = '\0';
710 return buf;
713 /* strcat and truncate. */
714 static char *pstrcat(char *buf, int buf_size, const char *s)
716 int len;
717 len = strlen(buf);
718 if (len < buf_size)
719 pstrcpy(buf + len, buf_size - len, s);
720 return buf;
723 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
725 int nb, nb_alloc;
726 void **pp;
728 nb = *nb_ptr;
729 pp = *ptab;
730 /* every power of two we double array size */
731 if ((nb & (nb - 1)) == 0) {
732 if (!nb)
733 nb_alloc = 1;
734 else
735 nb_alloc = nb * 2;
736 pp = realloc(pp, nb_alloc * sizeof(void *));
737 if (!pp)
738 error("memory full");
739 *ptab = pp;
741 pp[nb++] = data;
742 *nb_ptr = nb;
745 Section *new_section(const char *name, int sh_type, int sh_flags)
747 Section *sec;
748 void *data;
750 sec = malloc(sizeof(Section));
751 if (!sec)
752 error("memory full");
753 memset(sec, 0, sizeof(Section));
754 pstrcpy(sec->name, sizeof(sec->name), name);
755 sec->sh_type = sh_type;
756 sec->sh_flags = sh_flags;
757 switch(sh_type) {
758 case SHT_HASH:
759 case SHT_REL:
760 case SHT_DYNSYM:
761 case SHT_SYMTAB:
762 case SHT_DYNAMIC:
763 sec->sh_addralign = 4;
764 break;
765 case SHT_STRTAB:
766 sec->sh_addralign = 1;
767 break;
768 default:
769 sec->sh_addralign = 32; /* default conservative alignment */
770 break;
772 #ifdef WIN32
773 /* XXX: currently, a single malloc */
774 data = malloc(SECTION_VSIZE);
775 if (data == NULL)
776 error("could not alloc section '%s'", name);
777 #else
778 data = mmap(NULL, SECTION_VSIZE,
779 PROT_EXEC | PROT_READ | PROT_WRITE,
780 MAP_PRIVATE | MAP_ANONYMOUS,
781 -1, 0);
782 if (data == (void *)(-1))
783 error("could not mmap section '%s'", name);
784 #endif
785 sec->data = data;
786 sec->data_offset = 0;
788 /* only add section if not private */
789 if (!(sh_flags & SHF_PRIVATE)) {
790 sec->sh_num = nb_sections;
791 dynarray_add((void ***)&sections, &nb_sections, sec);
793 return sec;
796 /* reserve at least 'size' bytes in section 'sec' from sec->data_offset */
797 static void *section_ptr(Section *sec, unsigned long size)
799 return sec->data + sec->data_offset;
802 static void *section_ptr_add(Section *sec, unsigned long size)
804 void *ptr;
805 ptr = sec->data + sec->data_offset;
806 sec->data_offset += size;
807 return ptr;
810 /* return a reference to a section, and create it if it does not
811 exists */
812 Section *find_section(const char *name)
814 Section *sec;
815 int i;
816 for(i = 1; i < nb_sections; i++) {
817 sec = sections[i];
818 if (!strcmp(name, sec->name))
819 return sec;
821 /* sections are created as PROGBITS */
822 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
825 /* add a new relocation entry to symbol 'sym' in section 's' */
826 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
828 if (!sym->c)
829 put_extern_sym(sym, NULL, 0, 0);
830 /* now we can add ELF relocation info */
831 put_elf_reloc(symtab_section, s, offset, type, sym->c);
834 static inline int isid(int c)
836 return (c >= 'a' && c <= 'z') ||
837 (c >= 'A' && c <= 'Z') ||
838 c == '_';
841 static inline int isnum(int c)
843 return c >= '0' && c <= '9';
846 static inline int toup(int c)
848 if (ch >= 'a' && ch <= 'z')
849 return ch - 'a' + 'A';
850 else
851 return ch;
854 void printline(void)
856 BufferedFile **f;
858 if (file) {
859 for(f = include_stack; f < include_stack_ptr; f++)
860 fprintf(stderr, "In file included from %s:%d:\n",
861 (*f)->filename, (*f)->line_num);
862 if (file->line_num > 0) {
863 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
864 } else {
865 fprintf(stderr, "%s: ", file->filename);
867 } else {
868 fprintf(stderr, "tcc: ");
872 void error(const char *fmt, ...)
874 va_list ap;
875 va_start(ap, fmt);
876 printline();
877 vfprintf(stderr, fmt, ap);
878 fprintf(stderr, "\n");
879 exit(1);
880 va_end(ap);
883 void expect(const char *msg)
885 error("%s expected", msg);
888 void warning(const char *fmt, ...)
890 va_list ap;
892 va_start(ap, fmt);
893 printline();
894 fprintf(stderr, "warning: ");
895 vfprintf(stderr, fmt, ap);
896 fprintf(stderr, "\n");
897 va_end(ap);
900 void skip(int c)
902 if (tok != c)
903 error("'%c' expected", c);
904 next();
907 void test_lvalue(void)
909 if (!(vtop->r & VT_LVAL))
910 expect("lvalue");
913 TokenSym *tok_alloc(const char *str, int len)
915 TokenSym *ts, **pts, **ptable;
916 int h, i;
918 if (len <= 0)
919 len = strlen(str);
920 h = 1;
921 for(i=0;i<len;i++)
922 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
924 pts = &hash_ident[h];
925 while (1) {
926 ts = *pts;
927 if (!ts)
928 break;
929 if (ts->len == len && !memcmp(ts->str, str, len))
930 return ts;
931 pts = &(ts->hash_next);
934 if (tok_ident >= SYM_FIRST_ANOM)
935 error("memory full");
937 /* expand token table if needed */
938 i = tok_ident - TOK_IDENT;
939 if ((i % TOK_ALLOC_INCR) == 0) {
940 ptable = realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
941 if (!ptable)
942 error("memory full");
943 table_ident = ptable;
946 ts = malloc(sizeof(TokenSym) + len);
947 if (!ts)
948 error("memory full");
949 table_ident[i] = ts;
950 ts->tok = tok_ident++;
951 ts->len = len;
952 ts->hash_next = NULL;
953 memcpy(ts->str, str, len + 1);
954 *pts = ts;
955 return ts;
958 void add_char(char **pp, int c)
960 char *p;
961 p = *pp;
962 if (c == '\'' || c == '\"' || c == '\\') {
963 /* XXX: could be more precise if char or string */
964 *p++ = '\\';
966 if (c >= 32 && c <= 126) {
967 *p++ = c;
968 } else {
969 *p++ = '\\';
970 if (c == '\n') {
971 *p++ = 'n';
972 } else {
973 *p++ = '0' + ((c >> 6) & 7);
974 *p++ = '0' + ((c >> 3) & 7);
975 *p++ = '0' + (c & 7);
978 *pp = p;
981 /* XXX: buffer overflow */
982 char *get_tok_str(int v, CValue *cv)
984 static char buf[STRING_MAX_SIZE + 1];
985 TokenSym *ts;
986 char *p;
987 int i;
989 if (v == TOK_CINT || v == TOK_CUINT) {
990 sprintf(buf, "%u", cv->ui);
991 return buf;
992 } else if (v == TOK_CCHAR || v == TOK_LCHAR) {
993 p = buf;
994 *p++ = '\'';
995 add_char(&p, cv->i);
996 *p++ = '\'';
997 *p = '\0';
998 return buf;
999 } else if (v == TOK_STR || v == TOK_LSTR) {
1000 ts = cv->ts;
1001 p = buf;
1002 *p++ = '\"';
1003 for(i=0;i<ts->len;i++)
1004 add_char(&p, ts->str[i]);
1005 *p++ = '\"';
1006 *p = '\0';
1007 return buf;
1008 } else if (v < TOK_IDENT) {
1009 p = buf;
1010 *p++ = v;
1011 *p = '\0';
1012 return buf;
1013 } else if (v < tok_ident) {
1014 return table_ident[v - TOK_IDENT]->str;
1015 } else if (v >= SYM_FIRST_ANOM) {
1016 /* special name for anonymous symbol */
1017 sprintf(buf, "L.%u", v - SYM_FIRST_ANOM);
1018 return buf;
1019 } else {
1020 /* should never happen */
1021 return NULL;
1025 /* push, without hashing */
1026 Sym *sym_push2(Sym **ps, int v, int t, int c)
1028 Sym *s;
1029 s = malloc(sizeof(Sym));
1030 if (!s)
1031 error("memory full");
1032 s->v = v;
1033 s->t = t;
1034 s->c = c;
1035 s->next = NULL;
1036 /* add in stack */
1037 s->prev = *ps;
1038 *ps = s;
1039 return s;
1042 /* find a symbol and return its associated structure. 's' is the top
1043 of the symbol stack */
1044 Sym *sym_find2(Sym *s, int v)
1046 while (s) {
1047 if (s->v == v)
1048 return s;
1049 s = s->prev;
1051 return NULL;
1054 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1056 /* find a symbol and return its associated structure. 'st' is the
1057 symbol stack */
1058 Sym *sym_find1(SymStack *st, int v)
1060 Sym *s;
1062 s = st->hash[HASH_SYM(v)];
1063 while (s) {
1064 if (s->v == v)
1065 return s;
1066 s = s->hash_next;
1068 return NULL;
1071 Sym *sym_push1(SymStack *st, int v, int t, int c)
1073 Sym *s, **ps;
1074 s = sym_push2(&st->top, v, t, c);
1075 /* add in hash table */
1076 if (v) {
1077 ps = &st->hash[HASH_SYM(v)];
1078 s->hash_next = *ps;
1079 *ps = s;
1081 return s;
1084 /* find a symbol in the right symbol space */
1085 Sym *sym_find(int v)
1087 Sym *s;
1088 s = sym_find1(&local_stack, v);
1089 if (!s)
1090 s = sym_find1(&global_stack, v);
1091 return s;
1094 /* push a given symbol on the symbol stack */
1095 Sym *sym_push(int v, int t, int r, int c)
1097 Sym *s;
1098 if (local_stack.top)
1099 s = sym_push1(&local_stack, v, t, c);
1100 else
1101 s = sym_push1(&global_stack, v, t, c);
1102 s->r = r;
1103 return s;
1106 /* pop symbols until top reaches 'b' */
1107 void sym_pop(SymStack *st, Sym *b)
1109 Sym *s, *ss;
1111 s = st->top;
1112 while(s != b) {
1113 ss = s->prev;
1114 /* free hash table entry, except if symbol was freed (only
1115 used for #undef symbols) */
1116 if (s->v)
1117 st->hash[HASH_SYM(s->v)] = s->hash_next;
1118 free(s);
1119 s = ss;
1121 st->top = b;
1124 /* undefined a hashed symbol (used for #undef). Its name is set to
1125 zero */
1126 void sym_undef(SymStack *st, Sym *s)
1128 Sym **ss;
1129 ss = &st->hash[HASH_SYM(s->v)];
1130 while (*ss != NULL) {
1131 if (*ss == s)
1132 break;
1133 ss = &(*ss)->hash_next;
1135 *ss = s->hash_next;
1136 s->v = 0;
1139 /* I/O layer */
1141 BufferedFile *tcc_open(const char *filename)
1143 int fd;
1144 BufferedFile *bf;
1146 fd = open(filename, O_RDONLY);
1147 if (fd < 0)
1148 return NULL;
1149 bf = malloc(sizeof(BufferedFile));
1150 if (!bf) {
1151 close(fd);
1152 return NULL;
1154 bf->fd = fd;
1155 bf->buf_ptr = bf->buffer;
1156 bf->buf_end = bf->buffer;
1157 bf->buffer[0] = CH_EOB; /* put eob symbol */
1158 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1159 bf->line_num = 1;
1160 // printf("opening '%s'\n", filename);
1161 return bf;
1164 void tcc_close(BufferedFile *bf)
1166 total_lines += bf->line_num;
1167 close(bf->fd);
1168 free(bf);
1171 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1172 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1174 /* fill input buffer and return next char */
1175 int tcc_getc_slow(BufferedFile *bf)
1177 int len;
1178 /* only tries to read if really end of buffer */
1179 if (bf->buf_ptr >= bf->buf_end) {
1180 if (bf->fd != -1) {
1181 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1182 if (len < 0)
1183 len = 0;
1184 } else {
1185 len = 0;
1187 total_bytes += len;
1188 bf->buf_ptr = bf->buffer;
1189 bf->buf_end = bf->buffer + len;
1190 *bf->buf_end = CH_EOB;
1192 if (bf->buf_ptr < bf->buf_end) {
1193 return *bf->buf_ptr++;
1194 } else {
1195 bf->buf_ptr = bf->buf_end;
1196 return CH_EOF;
1200 /* no need to put that inline */
1201 void handle_eob(void)
1203 for(;;) {
1204 ch1 = tcc_getc_slow(file);
1205 if (ch1 != CH_EOF)
1206 return;
1208 if (include_stack_ptr == include_stack)
1209 return;
1210 /* add end of include file debug info */
1211 if (do_debug) {
1212 put_stabd(N_EINCL, 0, 0);
1214 /* pop include stack */
1215 tcc_close(file);
1216 include_stack_ptr--;
1217 file = *include_stack_ptr;
1221 /* read next char from current input file */
1222 static inline void inp(void)
1224 ch1 = TCC_GETC(file);
1225 /* end of buffer/file handling */
1226 if (ch1 == CH_EOB)
1227 handle_eob();
1228 if (ch1 == '\n')
1229 file->line_num++;
1230 // printf("ch1=%c 0x%x\n", ch1, ch1);
1233 /* input with '\\n' handling */
1234 static inline void minp(void)
1236 redo:
1237 ch = ch1;
1238 inp();
1239 if (ch == '\\' && ch1 == '\n') {
1240 inp();
1241 goto redo;
1243 //printf("ch=%c 0x%x\n", ch, ch);
1247 /* same as minp, but also skip comments */
1248 void cinp(void)
1250 int c;
1252 if (ch1 == '/') {
1253 inp();
1254 if (ch1 == '/') {
1255 /* single line C++ comments */
1256 inp();
1257 while (ch1 != '\n' && ch1 != -1)
1258 inp();
1259 inp();
1260 ch = ' '; /* return space */
1261 } else if (ch1 == '*') {
1262 /* C comments */
1263 inp();
1264 while (ch1 != -1) {
1265 c = ch1;
1266 inp();
1267 if (c == '*' && ch1 == '/') {
1268 inp();
1269 ch = ' '; /* return space */
1270 break;
1273 } else {
1274 ch = '/';
1276 } else {
1277 minp();
1281 void skip_spaces(void)
1283 while (ch == ' ' || ch == '\t')
1284 cinp();
1287 /* skip block of text until #else, #elif or #endif. skip also pairs of
1288 #if/#endif */
1289 void preprocess_skip(void)
1291 int a;
1292 a = 0;
1293 while (1) {
1294 while (ch != '\n') {
1295 if (ch == -1)
1296 expect("#endif");
1297 cinp();
1299 cinp();
1300 skip_spaces();
1301 if (ch == '#') {
1302 cinp();
1303 next_nomacro();
1304 if (a == 0 &&
1305 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1306 break;
1307 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1308 a++;
1309 else if (tok == TOK_ENDIF)
1310 a--;
1315 /* ParseState handling */
1317 /* XXX: currently, no include file info is stored. Thus, we cannot display
1318 accurate messages if the function or data definition spans multiple
1319 files */
1321 /* save current parse state in 's' */
1322 void save_parse_state(ParseState *s)
1324 s->line_num = file->line_num;
1325 s->macro_ptr = macro_ptr;
1326 s->tok = tok;
1327 s->tokc = tokc;
1330 /* restore parse state from 's' */
1331 void restore_parse_state(ParseState *s)
1333 file->line_num = s->line_num;
1334 macro_ptr = s->macro_ptr;
1335 tok = s->tok;
1336 tokc = s->tokc;
1339 /* return the number of additionnal 'ints' necessary to store the
1340 token */
1341 static inline int tok_ext_size(int t)
1343 switch(t) {
1344 /* 4 bytes */
1345 case TOK_CINT:
1346 case TOK_CUINT:
1347 case TOK_CCHAR:
1348 case TOK_LCHAR:
1349 case TOK_STR:
1350 case TOK_LSTR:
1351 case TOK_CFLOAT:
1352 case TOK_LINENUM:
1353 return 1;
1354 case TOK_CDOUBLE:
1355 case TOK_CLLONG:
1356 case TOK_CULLONG:
1357 return 2;
1358 case TOK_CLDOUBLE:
1359 return LDOUBLE_SIZE / 4;
1360 default:
1361 return 0;
1365 /* token string handling */
1367 static inline void tok_str_new(TokenString *s)
1369 s->str = NULL;
1370 s->len = 0;
1371 s->last_line_num = -1;
1374 static void tok_str_add(TokenString *s, int t)
1376 int len, *str;
1378 len = s->len;
1379 str = s->str;
1380 if ((len & 63) == 0) {
1381 str = realloc(str, (len + 64) * sizeof(int));
1382 if (!str)
1383 return;
1384 s->str = str;
1386 str[len++] = t;
1387 s->len = len;
1390 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1392 int n, i;
1393 tok_str_add(s, t);
1394 n = tok_ext_size(t);
1395 for(i=0;i<n;i++)
1396 tok_str_add(s, cv->tab[i]);
1399 /* add the current parse token in token string 's' */
1400 static void tok_str_add_tok(TokenString *s)
1402 CValue cval;
1404 /* save line number info */
1405 if (file->line_num != s->last_line_num) {
1406 s->last_line_num = file->line_num;
1407 cval.i = s->last_line_num;
1408 tok_str_add2(s, TOK_LINENUM, &cval);
1410 tok_str_add2(s, tok, &tokc);
1413 /* get a token from an integer array and increment pointer accordingly */
1414 static int tok_get(int **tok_str, CValue *cv)
1416 int *p, t, n, i;
1418 p = *tok_str;
1419 t = *p++;
1420 n = tok_ext_size(t);
1421 for(i=0;i<n;i++)
1422 cv->tab[i] = *p++;
1423 *tok_str = p;
1424 return t;
1427 /* eval an expression for #if/#elif */
1428 int expr_preprocess(void)
1430 int c, t;
1431 TokenString str;
1433 tok_str_new(&str);
1434 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1435 next(); /* do macro subst */
1436 if (tok == TOK_DEFINED) {
1437 next_nomacro();
1438 t = tok;
1439 if (t == '(')
1440 next_nomacro();
1441 c = sym_find1(&define_stack, tok) != 0;
1442 if (t == '(')
1443 next_nomacro();
1444 tok = TOK_CINT;
1445 tokc.i = c;
1446 } else if (tok >= TOK_IDENT) {
1447 /* if undefined macro */
1448 tok = TOK_CINT;
1449 tokc.i = 0;
1451 tok_str_add_tok(&str);
1453 tok_str_add(&str, -1); /* simulate end of file */
1454 tok_str_add(&str, 0);
1455 /* now evaluate C constant expression */
1456 macro_ptr = str.str;
1457 next();
1458 c = expr_const();
1459 macro_ptr = NULL;
1460 free(str.str);
1461 return c != 0;
1464 #if defined(DEBUG) || defined(PP_DEBUG)
1465 void tok_print(int *str)
1467 int t;
1468 CValue cval;
1470 while (1) {
1471 t = tok_get(&str, &cval);
1472 if (!t)
1473 break;
1474 printf(" %s", get_tok_str(t, &cval));
1476 printf("\n");
1478 #endif
1480 /* parse after #define */
1481 void parse_define(void)
1483 Sym *s, *first, **ps;
1484 int v, t, varg, is_vaargs;
1485 TokenString str;
1487 v = tok;
1488 /* XXX: should check if same macro (ANSI) */
1489 first = NULL;
1490 t = MACRO_OBJ;
1491 /* '(' must be just after macro definition for MACRO_FUNC */
1492 if (ch == '(') {
1493 next_nomacro();
1494 next_nomacro();
1495 ps = &first;
1496 while (tok != ')') {
1497 varg = tok;
1498 next_nomacro();
1499 is_vaargs = 0;
1500 if (varg == TOK_DOTS) {
1501 varg = TOK___VA_ARGS__;
1502 is_vaargs = 1;
1503 } else if (tok == TOK_DOTS && gnu_ext) {
1504 is_vaargs = 1;
1505 next_nomacro();
1507 if (varg < TOK_IDENT)
1508 error("badly punctuated parameter list");
1509 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1510 *ps = s;
1511 ps = &s->next;
1512 if (tok != ',')
1513 break;
1514 next_nomacro();
1516 t = MACRO_FUNC;
1518 tok_str_new(&str);
1519 while (1) {
1520 skip_spaces();
1521 if (ch == '\n' || ch == -1)
1522 break;
1523 next_nomacro();
1524 tok_str_add2(&str, tok, &tokc);
1526 tok_str_add(&str, 0);
1527 #ifdef PP_DEBUG
1528 printf("define %s %d: ", get_tok_str(v, NULL), t);
1529 tok_print(str.str);
1530 #endif
1531 s = sym_push1(&define_stack, v, t, (int)str.str);
1532 s->next = first;
1535 void preprocess(void)
1537 int size, i, c;
1538 char buf[1024], *q, *p;
1539 char buf1[1024];
1540 BufferedFile *f;
1541 Sym *s;
1543 return_linefeed = 1; /* linefeed will be returned as a token */
1544 cinp();
1545 next_nomacro();
1546 redo:
1547 if (tok == TOK_DEFINE) {
1548 next_nomacro();
1549 parse_define();
1550 } else if (tok == TOK_UNDEF) {
1551 next_nomacro();
1552 s = sym_find1(&define_stack, tok);
1553 /* undefine symbol by putting an invalid name */
1554 if (s)
1555 sym_undef(&define_stack, s);
1556 } else if (tok == TOK_INCLUDE) {
1557 skip_spaces();
1558 if (ch == '<') {
1559 c = '>';
1560 goto read_name;
1561 } else if (ch == '\"') {
1562 c = ch;
1563 read_name:
1564 minp();
1565 q = buf;
1566 while (ch != c && ch != '\n' && ch != -1) {
1567 if ((q - buf) < sizeof(buf) - 1)
1568 *q++ = ch;
1569 minp();
1571 *q = '\0';
1572 } else {
1573 next();
1574 if (tok != TOK_STR)
1575 error("#include syntax error");
1576 pstrcpy(buf, sizeof(buf), get_tok_str(tok, &tokc));
1577 c = '\"';
1579 /* eat all spaces and comments after include */
1580 /* XXX: slightly incorrect */
1581 while (ch1 != '\n' && ch1 != -1)
1582 inp();
1584 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1585 error("memory full");
1586 if (c == '\"') {
1587 /* first search in current dir if "header.h" */
1588 size = 0;
1589 p = strrchr(file->filename, '/');
1590 if (p)
1591 size = p + 1 - file->filename;
1592 if (size > sizeof(buf1) - 1)
1593 size = sizeof(buf1) - 1;
1594 memcpy(buf1, file->filename, size);
1595 buf1[size] = '\0';
1596 pstrcat(buf1, sizeof(buf1), buf);
1597 f = tcc_open(buf1);
1598 if (f)
1599 goto found;
1601 /* now search in standard include path */
1602 for(i=nb_include_paths - 1;i>=0;i--) {
1603 strcpy(buf1, include_paths[i]);
1604 strcat(buf1, "/");
1605 strcat(buf1, buf);
1606 f = tcc_open(buf1);
1607 if (f)
1608 goto found;
1610 error("include file '%s' not found", buf);
1611 f = NULL;
1612 found:
1613 /* push current file in stack */
1614 /* XXX: fix current line init */
1615 *include_stack_ptr++ = file;
1616 file = f;
1617 /* add include file debug info */
1618 if (do_debug) {
1619 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1621 ch = '\n';
1622 goto the_end;
1623 } else if (tok == TOK_IFNDEF) {
1624 c = 1;
1625 goto do_ifdef;
1626 } else if (tok == TOK_IF) {
1627 c = expr_preprocess();
1628 goto do_if;
1629 } else if (tok == TOK_IFDEF) {
1630 c = 0;
1631 do_ifdef:
1632 next_nomacro();
1633 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1634 do_if:
1635 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1636 error("memory full");
1637 *ifdef_stack_ptr++ = c;
1638 goto test_skip;
1639 } else if (tok == TOK_ELSE) {
1640 if (ifdef_stack_ptr == ifdef_stack)
1641 error("#else without matching #if");
1642 if (ifdef_stack_ptr[-1] & 2)
1643 error("#else after #else");
1644 c = (ifdef_stack_ptr[-1] ^= 3);
1645 goto test_skip;
1646 } else if (tok == TOK_ELIF) {
1647 if (ifdef_stack_ptr == ifdef_stack)
1648 error("#elif without matching #if");
1649 c = ifdef_stack_ptr[-1];
1650 if (c > 1)
1651 error("#elif after #else");
1652 /* last #if/#elif expression was true: we skip */
1653 if (c == 1)
1654 goto skip;
1655 c = expr_preprocess();
1656 ifdef_stack_ptr[-1] = c;
1657 test_skip:
1658 if (!(c & 1)) {
1659 skip:
1660 preprocess_skip();
1661 goto redo;
1663 } else if (tok == TOK_ENDIF) {
1664 if (ifdef_stack_ptr == ifdef_stack)
1665 error("#endif without matching #if");
1666 ifdef_stack_ptr--;
1667 } else if (tok == TOK_LINE) {
1668 next();
1669 if (tok != TOK_CINT)
1670 error("#line");
1671 file->line_num = tokc.i;
1672 skip_spaces();
1673 if (ch != '\n') {
1674 next();
1675 if (tok != TOK_STR)
1676 error("#line");
1677 pstrcpy(file->filename, sizeof(file->filename),
1678 get_tok_str(tok, &tokc));
1680 } else if (tok == TOK_ERROR) {
1681 error("#error");
1683 /* ignore other preprocess commands or #! for C scripts */
1684 while (tok != TOK_LINEFEED && tok != TOK_EOF)
1685 next_nomacro();
1686 the_end:
1687 return_linefeed = 0;
1690 /* read a number in base b */
1691 static int getn(int b)
1693 int n, t;
1694 n = 0;
1695 while (1) {
1696 if (ch >= 'a' && ch <= 'f')
1697 t = ch - 'a' + 10;
1698 else if (ch >= 'A' && ch <= 'F')
1699 t = ch - 'A' + 10;
1700 else if (isnum(ch))
1701 t = ch - '0';
1702 else
1703 break;
1704 if (t < 0 || t >= b)
1705 break;
1706 n = n * b + t;
1707 cinp();
1709 return n;
1712 /* read a character for string or char constant and eval escape codes */
1713 static int getq(void)
1715 int c;
1717 c = ch;
1718 minp();
1719 if (c == '\\') {
1720 if (isnum(ch)) {
1721 /* at most three octal digits */
1722 c = ch - '0';
1723 minp();
1724 if (isnum(ch)) {
1725 c = c * 8 + ch - '0';
1726 minp();
1727 if (isnum(ch)) {
1728 c = c * 8 + ch - '0';
1729 minp();
1732 return c;
1733 } else if (ch == 'x') {
1734 minp();
1735 return getn(16);
1736 } else {
1737 if (ch == 'a')
1738 c = '\a';
1739 else if (ch == 'b')
1740 c = '\b';
1741 else if (ch == 'f')
1742 c = '\f';
1743 else if (ch == 'n')
1744 c = '\n';
1745 else if (ch == 'r')
1746 c = '\r';
1747 else if (ch == 't')
1748 c = '\t';
1749 else if (ch == 'v')
1750 c = '\v';
1751 else if (ch == 'e' && gnu_ext)
1752 c = 27;
1753 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
1754 c = ch;
1755 else
1756 error("invalid escaped char");
1757 minp();
1760 return c;
1763 /* we use 64 bit numbers */
1764 #define BN_SIZE 2
1766 /* bn = (bn << shift) | or_val */
1767 void bn_lshift(unsigned int *bn, int shift, int or_val)
1769 int i;
1770 unsigned int v;
1771 for(i=0;i<BN_SIZE;i++) {
1772 v = bn[i];
1773 bn[i] = (v << shift) | or_val;
1774 or_val = v >> (32 - shift);
1778 void bn_zero(unsigned int *bn)
1780 int i;
1781 for(i=0;i<BN_SIZE;i++) {
1782 bn[i] = 0;
1786 void parse_number(void)
1788 int b, t, shift, frac_bits, s, exp_val;
1789 char *q;
1790 unsigned int bn[BN_SIZE];
1791 double d;
1793 /* number */
1794 q = token_buf;
1795 t = ch;
1796 cinp();
1797 *q++ = t;
1798 b = 10;
1799 if (t == '.') {
1800 /* special dot handling */
1801 if (ch >= '0' && ch <= '9') {
1802 goto float_frac_parse;
1803 } else if (ch == '.') {
1804 cinp();
1805 if (ch != '.')
1806 expect("'.'");
1807 cinp();
1808 tok = TOK_DOTS;
1809 } else {
1810 /* dots */
1811 tok = t;
1813 return;
1814 } else if (t == '0') {
1815 if (ch == 'x' || ch == 'X') {
1816 q--;
1817 cinp();
1818 b = 16;
1819 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
1820 q--;
1821 cinp();
1822 b = 2;
1825 /* parse all digits. cannot check octal numbers at this stage
1826 because of floating point constants */
1827 while (1) {
1828 if (ch >= 'a' && ch <= 'f')
1829 t = ch - 'a' + 10;
1830 else if (ch >= 'A' && ch <= 'F')
1831 t = ch - 'A' + 10;
1832 else if (isnum(ch))
1833 t = ch - '0';
1834 else
1835 break;
1836 if (t >= b)
1837 break;
1838 if (q >= token_buf + STRING_MAX_SIZE) {
1839 num_too_long:
1840 error("number too long");
1842 *q++ = ch;
1843 cinp();
1845 if (ch == '.' ||
1846 ((ch == 'e' || ch == 'E') && b == 10) ||
1847 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
1848 if (b != 10) {
1849 /* NOTE: strtox should support that for hexa numbers, but
1850 non ISOC99 libcs do not support it, so we prefer to do
1851 it by hand */
1852 /* hexadecimal or binary floats */
1853 /* XXX: handle overflows */
1854 *q = '\0';
1855 if (b == 16)
1856 shift = 4;
1857 else
1858 shift = 2;
1859 bn_zero(bn);
1860 q = token_buf;
1861 while (1) {
1862 t = *q++;
1863 if (t == '\0') {
1864 break;
1865 } else if (t >= 'a') {
1866 t = t - 'a' + 10;
1867 } else if (t >= 'A') {
1868 t = t - 'A' + 10;
1869 } else {
1870 t = t - '0';
1872 bn_lshift(bn, shift, t);
1874 frac_bits = 0;
1875 if (ch == '.') {
1876 cinp();
1877 while (1) {
1878 t = ch;
1879 if (t >= 'a' && t <= 'f') {
1880 t = t - 'a' + 10;
1881 } else if (t >= 'A' && t <= 'F') {
1882 t = t - 'A' + 10;
1883 } else if (t >= '0' && t <= '9') {
1884 t = t - '0';
1885 } else {
1886 break;
1888 if (t >= b)
1889 error("invalid digit");
1890 bn_lshift(bn, shift, t);
1891 frac_bits += shift;
1892 cinp();
1895 if (ch != 'p' && ch != 'P')
1896 error("exponent expected");
1897 cinp();
1898 s = 1;
1899 exp_val = 0;
1900 if (ch == '+') {
1901 cinp();
1902 } else if (ch == '-') {
1903 s = -1;
1904 cinp();
1906 if (ch < '0' || ch > '9')
1907 error("exponent digits expected");
1908 while (ch >= '0' && ch <= '9') {
1909 exp_val = exp_val * 10 + ch - '0';
1910 cinp();
1912 exp_val = exp_val * s;
1914 /* now we can generate the number */
1915 /* XXX: should patch directly float number */
1916 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
1917 d = ldexp(d, exp_val - frac_bits);
1918 t = toup(ch);
1919 if (t == 'F') {
1920 cinp();
1921 tok = TOK_CFLOAT;
1922 /* float : should handle overflow */
1923 tokc.f = (float)d;
1924 } else if (t == 'L') {
1925 cinp();
1926 tok = TOK_CLDOUBLE;
1927 /* XXX: not large enough */
1928 tokc.ld = (long double)d;
1929 } else {
1930 tok = TOK_CDOUBLE;
1931 tokc.d = d;
1933 } else {
1934 /* decimal floats */
1935 if (ch == '.') {
1936 if (q >= token_buf + STRING_MAX_SIZE)
1937 goto num_too_long;
1938 *q++ = ch;
1939 cinp();
1940 float_frac_parse:
1941 while (ch >= '0' && ch <= '9') {
1942 if (q >= token_buf + STRING_MAX_SIZE)
1943 goto num_too_long;
1944 *q++ = ch;
1945 cinp();
1948 if (ch == 'e' || ch == 'E') {
1949 if (q >= token_buf + STRING_MAX_SIZE)
1950 goto num_too_long;
1951 *q++ = ch;
1952 cinp();
1953 if (ch == '-' || ch == '+') {
1954 if (q >= token_buf + STRING_MAX_SIZE)
1955 goto num_too_long;
1956 *q++ = ch;
1957 cinp();
1959 if (ch < '0' || ch > '9')
1960 error("exponent digits expected");
1961 while (ch >= '0' && ch <= '9') {
1962 if (q >= token_buf + STRING_MAX_SIZE)
1963 goto num_too_long;
1964 *q++ = ch;
1965 cinp();
1968 *q = '\0';
1969 t = toup(ch);
1970 errno = 0;
1971 if (t == 'F') {
1972 cinp();
1973 tok = TOK_CFLOAT;
1974 tokc.f = strtof(token_buf, NULL);
1975 } else if (t == 'L') {
1976 cinp();
1977 tok = TOK_CLDOUBLE;
1978 tokc.ld = strtold(token_buf, NULL);
1979 } else {
1980 tok = TOK_CDOUBLE;
1981 tokc.d = strtod(token_buf, NULL);
1984 } else {
1985 unsigned long long n, n1;
1986 int lcount;
1988 /* integer number */
1989 *q = '\0';
1990 q = token_buf;
1991 if (b == 10 && *q == '0') {
1992 b = 8;
1993 q++;
1995 n = 0;
1996 while(1) {
1997 t = *q++;
1998 /* no need for checks except for base 10 / 8 errors */
1999 if (t == '\0') {
2000 break;
2001 } else if (t >= 'a') {
2002 t = t - 'a' + 10;
2003 } else if (t >= 'A') {
2004 t = t - 'A' + 10;
2005 } else {
2006 t = t - '0';
2007 if (t >= b)
2008 error("invalid digit");
2010 n1 = n;
2011 n = n * b + t;
2012 /* detect overflow */
2013 if (n < n1)
2014 error("integer constant overflow");
2017 /* XXX: not exactly ANSI compliant */
2018 if ((n & 0xffffffff00000000LL) != 0) {
2019 if ((n >> 63) != 0)
2020 tok = TOK_CULLONG;
2021 else
2022 tok = TOK_CLLONG;
2023 } else if (n > 0x7fffffff) {
2024 tok = TOK_CUINT;
2025 } else {
2026 tok = TOK_CINT;
2028 lcount = 0;
2029 for(;;) {
2030 t = toup(ch);
2031 if (t == 'L') {
2032 if (lcount >= 2)
2033 error("three 'l' in integer constant");
2034 lcount++;
2035 if (lcount == 2) {
2036 if (tok == TOK_CINT)
2037 tok = TOK_CLLONG;
2038 else if (tok == TOK_CUINT)
2039 tok = TOK_CULLONG;
2041 cinp();
2042 } else if (t == 'U') {
2043 if (tok == TOK_CINT)
2044 tok = TOK_CUINT;
2045 else if (tok == TOK_CLLONG)
2046 tok = TOK_CULLONG;
2047 cinp();
2048 } else {
2049 break;
2052 if (tok == TOK_CINT || tok == TOK_CUINT)
2053 tokc.ui = n;
2054 else
2055 tokc.ull = n;
2060 /* return next token without macro substitution */
2061 void next_nomacro1(void)
2063 int b;
2064 char *q;
2065 TokenSym *ts;
2067 /* skip spaces */
2068 while(1) {
2069 while (ch == '\n') {
2070 /* during preprocessor parsing, '\n' is a token */
2071 if (return_linefeed) {
2072 tok = TOK_LINEFEED;
2073 return;
2075 cinp();
2076 while (ch == ' ' || ch == '\t')
2077 cinp();
2078 if (ch == '#') {
2079 /* preprocessor command if # at start of line after
2080 spaces */
2081 preprocess();
2084 if (ch != ' ' && ch != '\t' && ch != '\f')
2085 break;
2086 cinp();
2088 if (isid(ch)) {
2089 q = token_buf;
2090 *q++ = ch;
2091 cinp();
2092 if (q[-1] == 'L') {
2093 if (ch == '\'') {
2094 tok = TOK_LCHAR;
2095 goto char_const;
2097 if (ch == '\"') {
2098 tok = TOK_LSTR;
2099 goto str_const;
2102 while (isid(ch) || isnum(ch)) {
2103 if (q >= token_buf + STRING_MAX_SIZE)
2104 error("ident too long");
2105 *q++ = ch;
2106 cinp();
2108 *q = '\0';
2109 ts = tok_alloc(token_buf, q - token_buf);
2110 tok = ts->tok;
2111 } else if (isnum(ch) || ch == '.') {
2112 parse_number();
2113 } else if (ch == '\'') {
2114 tok = TOK_CCHAR;
2115 char_const:
2116 minp();
2117 b = getq();
2118 /* this cast is needed if >= 128 */
2119 if (tok == TOK_CCHAR)
2120 b = (char)b;
2121 tokc.i = b;
2122 if (ch != '\'')
2123 expect("\'");
2124 minp();
2125 } else if (ch == '\"') {
2126 tok = TOK_STR;
2127 str_const:
2128 minp();
2129 q = token_buf;
2130 while (ch != '\"') {
2131 b = getq();
2132 if (ch == -1)
2133 error("unterminated string");
2134 if (q >= token_buf + STRING_MAX_SIZE)
2135 error("string too long");
2136 *q++ = b;
2138 *q = '\0';
2139 tokc.ts = tok_alloc(token_buf, q - token_buf);
2140 minp();
2141 } else {
2142 q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2143 /* two chars */
2144 tok = ch;
2145 cinp();
2146 while (*q) {
2147 if (*q == tok && q[1] == ch) {
2148 cinp();
2149 tok = q[2] & 0xff;
2150 /* three chars tests */
2151 if (tok == TOK_SHL || tok == TOK_SAR) {
2152 if (ch == '=') {
2153 tok = tok | 0x80;
2154 cinp();
2156 } else if (tok == TOK_DOTS) {
2157 if (ch != '.')
2158 error("parse error");
2159 cinp();
2161 return;
2163 q = q + 3;
2165 /* single char substitutions */
2166 if (tok == '<')
2167 tok = TOK_LT;
2168 else if (tok == '>')
2169 tok = TOK_GT;
2173 /* return next token without macro substitution. Can read input from
2174 macro_ptr buffer */
2175 void next_nomacro()
2177 if (macro_ptr) {
2178 redo:
2179 tok = *macro_ptr;
2180 if (tok) {
2181 tok = tok_get(&macro_ptr, &tokc);
2182 if (tok == TOK_LINENUM) {
2183 file->line_num = tokc.i;
2184 goto redo;
2187 } else {
2188 next_nomacro1();
2192 /* substitute args in macro_str and return allocated string */
2193 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2195 int *st, last_tok, t, notfirst;
2196 Sym *s;
2197 TokenSym *ts;
2198 CValue cval;
2199 TokenString str;
2201 tok_str_new(&str);
2202 last_tok = 0;
2203 while(1) {
2204 t = tok_get(&macro_str, &cval);
2205 if (!t)
2206 break;
2207 if (t == '#') {
2208 /* stringize */
2209 t = tok_get(&macro_str, &cval);
2210 if (!t)
2211 break;
2212 s = sym_find2(args, t);
2213 if (s) {
2214 token_buf[0] = '\0';
2215 st = (int *)s->c;
2216 notfirst = 0;
2217 while (*st) {
2218 if (notfirst)
2219 pstrcat(token_buf, sizeof(token_buf), " ");
2220 t = tok_get(&st, &cval);
2221 pstrcat(token_buf, sizeof(token_buf), get_tok_str(t, &cval));
2222 notfirst = 1;
2224 #ifdef PP_DEBUG
2225 printf("stringize: %s\n", token_buf);
2226 #endif
2227 /* add string */
2228 ts = tok_alloc(token_buf, 0);
2229 cval.ts = ts;
2230 tok_str_add2(&str, TOK_STR, &cval);
2231 } else {
2232 tok_str_add2(&str, t, &cval);
2234 } else if (t >= TOK_IDENT) {
2235 s = sym_find2(args, t);
2236 if (s) {
2237 st = (int *)s->c;
2238 /* if '##' is present before or after, no arg substitution */
2239 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2240 /* special case for var arg macros : ## eats the
2241 ',' if empty VA_ARGS riable. */
2242 /* XXX: test of the ',' is not 100%
2243 reliable. should fix it to avoid security
2244 problems */
2245 if (gnu_ext && s->t && *st == 0 &&
2246 last_tok == TOK_TWOSHARPS &&
2247 str.len >= 2&& str.str[str.len - 2] == ',') {
2248 /* suppress ',' '##' */
2249 str.len -= 2;
2250 } else {
2251 while (*st)
2252 tok_str_add(&str, *st++);
2254 } else {
2255 macro_subst(&str, nested_list, st);
2257 } else {
2258 tok_str_add(&str, t);
2260 } else {
2261 tok_str_add2(&str, t, &cval);
2263 last_tok = t;
2265 tok_str_add(&str, 0);
2266 return str.str;
2269 /* handle the '##' operator */
2270 int *macro_twosharps(int *macro_str)
2272 TokenSym *ts;
2273 int *macro_ptr1;
2274 int t;
2275 char *p;
2276 CValue cval;
2277 TokenString macro_str1;
2279 tok_str_new(&macro_str1);
2280 tok = 0;
2281 while (1) {
2282 next_nomacro();
2283 if (tok == 0)
2284 break;
2285 while (*macro_ptr == TOK_TWOSHARPS) {
2286 macro_ptr++;
2287 macro_ptr1 = macro_ptr;
2288 t = *macro_ptr;
2289 if (t) {
2290 t = tok_get(&macro_ptr, &cval);
2291 /* XXX: we handle only most common cases:
2292 ident + ident or ident + number */
2293 if (tok >= TOK_IDENT &&
2294 (t >= TOK_IDENT || t == TOK_CINT)) {
2295 p = get_tok_str(tok, &tokc);
2296 pstrcpy(token_buf, sizeof(token_buf), p);
2297 p = get_tok_str(t, &cval);
2298 pstrcat(token_buf, sizeof(token_buf), p);
2299 ts = tok_alloc(token_buf, 0);
2300 tok = ts->tok; /* modify current token */
2301 } else {
2302 /* cannot merge tokens: skip '##' */
2303 macro_ptr = macro_ptr1;
2304 break;
2308 tok_str_add2(&macro_str1, tok, &tokc);
2310 tok_str_add(&macro_str1, 0);
2311 return macro_str1.str;
2314 /* do macro substitution of macro_str and add result to
2315 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2316 substituted. 'nested_list' is the list of all macros we got inside
2317 to avoid recursing. */
2318 void macro_subst(TokenString *tok_str,
2319 Sym **nested_list, int *macro_str)
2321 Sym *s, *args, *sa, *sa1;
2322 int parlevel, *mstr, t, *saved_macro_ptr;
2323 int mstr_allocated, *macro_str1;
2324 CValue cval;
2325 TokenString str;
2327 saved_macro_ptr = macro_ptr;
2328 macro_ptr = macro_str;
2329 macro_str1 = NULL;
2330 if (macro_str) {
2331 /* first scan for '##' operator handling */
2332 macro_str1 = macro_twosharps(macro_str);
2333 macro_ptr = macro_str1;
2336 while (1) {
2337 next_nomacro();
2338 if (tok == 0)
2339 break;
2340 /* special macros */
2341 if (tok == TOK___LINE__) {
2342 cval.i = file->line_num;
2343 tok_str_add2(tok_str, TOK_CINT, &cval);
2344 } else if (tok == TOK___FILE__) {
2345 cval.ts = tok_alloc(file->filename, 0);
2346 tok_str_add2(tok_str, TOK_STR, &cval);
2347 } else if (tok == TOK___DATE__) {
2348 cval.ts = tok_alloc("Jan 1 1970", 0);
2349 tok_str_add2(tok_str, TOK_STR, &cval);
2350 } else if (tok == TOK___TIME__) {
2351 cval.ts = tok_alloc("00:00:00", 0);
2352 tok_str_add2(tok_str, TOK_STR, &cval);
2353 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
2354 /* if symbol is a macro, prepare substitution */
2355 /* if nested substitution, do nothing */
2356 if (sym_find2(*nested_list, tok))
2357 goto no_subst;
2358 mstr = (int *)s->c;
2359 mstr_allocated = 0;
2360 if (s->t == MACRO_FUNC) {
2361 /* NOTE: we do not use next_nomacro to avoid eating the
2362 next token. XXX: find better solution */
2363 if (macro_ptr) {
2364 t = *macro_ptr;
2365 } else {
2366 while (ch == ' ' || ch == '\t' || ch == '\n')
2367 cinp();
2368 t = ch;
2370 if (t != '(') /* no macro subst */
2371 goto no_subst;
2373 /* argument macro */
2374 next_nomacro();
2375 next_nomacro();
2376 args = NULL;
2377 sa = s->next;
2378 /* NOTE: empty args are allowed, except if no args */
2379 for(;;) {
2380 /* handle '()' case */
2381 if (!args && tok == ')')
2382 break;
2383 if (!sa)
2384 error("macro '%s' used with too many args",
2385 get_tok_str(s->v, 0));
2386 tok_str_new(&str);
2387 parlevel = 0;
2388 /* NOTE: non zero sa->t indicates VA_ARGS */
2389 while ((parlevel > 0 ||
2390 (tok != ')' &&
2391 (tok != ',' || sa->t))) &&
2392 tok != -1) {
2393 if (tok == '(')
2394 parlevel++;
2395 else if (tok == ')')
2396 parlevel--;
2397 tok_str_add2(&str, tok, &tokc);
2398 next_nomacro();
2400 tok_str_add(&str, 0);
2401 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2402 sa = sa->next;
2403 if (tok == ')') {
2404 /* special case for gcc var args: add an empty
2405 var arg argument if it is omitted */
2406 if (sa && sa->t && gnu_ext)
2407 continue;
2408 else
2409 break;
2411 if (tok != ',')
2412 expect(",");
2413 next_nomacro();
2415 if (sa) {
2416 error("macro '%s' used with too few args",
2417 get_tok_str(s->v, 0));
2420 /* now subst each arg */
2421 mstr = macro_arg_subst(nested_list, mstr, args);
2422 /* free memory */
2423 sa = args;
2424 while (sa) {
2425 sa1 = sa->prev;
2426 free((int *)sa->c);
2427 free(sa);
2428 sa = sa1;
2430 mstr_allocated = 1;
2432 sym_push2(nested_list, s->v, 0, 0);
2433 macro_subst(tok_str, nested_list, mstr);
2434 /* pop nested defined symbol */
2435 sa1 = *nested_list;
2436 *nested_list = sa1->prev;
2437 free(sa1);
2438 if (mstr_allocated)
2439 free(mstr);
2440 } else {
2441 no_subst:
2442 /* no need to add if reading input stream */
2443 if (!macro_str)
2444 return;
2445 tok_str_add2(tok_str, tok, &tokc);
2447 /* only replace one macro while parsing input stream */
2448 if (!macro_str)
2449 return;
2451 macro_ptr = saved_macro_ptr;
2452 if (macro_str1)
2453 free(macro_str1);
2456 /* return next token with macro substitution */
2457 void next(void)
2459 Sym *nested_list;
2460 TokenString str;
2462 /* special 'ungettok' case for label parsing */
2463 if (tok1) {
2464 tok = tok1;
2465 tokc = tok1c;
2466 tok1 = 0;
2467 } else {
2468 redo:
2469 if (!macro_ptr) {
2470 /* if not reading from macro substituted string, then try
2471 to substitute */
2472 /* XXX: optimize non macro case */
2473 tok_str_new(&str);
2474 nested_list = NULL;
2475 macro_subst(&str, &nested_list, NULL);
2476 if (str.str) {
2477 tok_str_add(&str, 0);
2478 macro_ptr = str.str;
2479 macro_ptr_allocated = str.str;
2480 goto redo;
2482 if (tok == 0)
2483 goto redo;
2484 } else {
2485 next_nomacro();
2486 if (tok == 0) {
2487 /* end of macro string: free it */
2488 free(macro_ptr_allocated);
2489 macro_ptr = NULL;
2490 goto redo;
2494 #if defined(DEBUG)
2495 printf("token = %s\n", get_tok_str(tok, &tokc));
2496 #endif
2499 void swap(int *p, int *q)
2501 int t;
2502 t = *p;
2503 *p = *q;
2504 *q = t;
2507 void vsetc(int t, int r, CValue *vc)
2509 if (vtop >= vstack + VSTACK_SIZE)
2510 error("memory full");
2511 /* cannot let cpu flags if other instruction are generated */
2512 /* XXX: VT_JMP test too ? */
2513 if ((vtop->r & VT_VALMASK) == VT_CMP)
2514 gv(RC_INT);
2515 vtop++;
2516 vtop->t = t;
2517 vtop->r = r;
2518 vtop->r2 = VT_CONST;
2519 vtop->c = *vc;
2522 /* push integer constant */
2523 void vpushi(int v)
2525 CValue cval;
2526 cval.i = v;
2527 vsetc(VT_INT, VT_CONST, &cval);
2530 /* Return a static symbol pointing to a section */
2531 static Sym *get_sym_ref(int t, Section *sec,
2532 unsigned long offset, unsigned long size)
2534 int v;
2535 Sym *sym;
2537 v = anon_sym++;
2538 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2539 sym->r = VT_CONST | VT_SYM;
2540 put_extern_sym(sym, sec, offset, size);
2541 return sym;
2544 /* push a reference to a section offset by adding a dummy symbol */
2545 void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
2547 CValue cval;
2549 cval.sym = get_sym_ref(t, sec, offset, size);
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 Sym *sym;
2764 int *ptr;
2765 unsigned long offset;
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 offset = (data_section->data_offset + align - 1) & -align;
2772 data_section->data_offset = offset;
2773 /* XXX: not portable yet */
2774 ptr = section_ptr_add(data_section, size);
2775 size = size >> 2;
2776 for(i=0;i<size;i++)
2777 ptr[i] = vtop->c.tab[i];
2778 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
2779 vtop->r |= VT_LVAL | VT_SYM;
2780 vtop->c.sym = sym;
2782 #ifdef CONFIG_TCC_BCHECK
2783 if (vtop->r & VT_MUSTBOUND)
2784 gbound();
2785 #endif
2787 r = vtop->r & VT_VALMASK;
2788 /* need to reload if:
2789 - constant
2790 - lvalue (need to dereference pointer)
2791 - already a register, but not in the right class */
2792 if (r >= VT_CONST ||
2793 (vtop->r & VT_LVAL) ||
2794 !(reg_classes[r] & rc) ||
2795 ((vtop->t & VT_BTYPE) == VT_LLONG &&
2796 !(reg_classes[vtop->r2] & rc))) {
2797 r = get_reg(rc);
2798 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
2799 /* two register type load : expand to two words
2800 temporarily */
2801 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
2802 /* load constant */
2803 ll = vtop->c.ull;
2804 vtop->c.ui = ll; /* first word */
2805 load(r, vtop);
2806 vtop->r = r; /* save register value */
2807 vpushi(ll >> 32); /* second word */
2808 } else if (r >= VT_CONST ||
2809 (vtop->r & VT_LVAL)) {
2810 /* load from memory */
2811 load(r, vtop);
2812 vdup();
2813 vtop[-1].r = r; /* save register value */
2814 /* increment pointer to get second word */
2815 vtop->t = VT_INT;
2816 gaddrof();
2817 vpushi(4);
2818 gen_op('+');
2819 vtop->r |= VT_LVAL;
2820 } else {
2821 /* move registers */
2822 load(r, vtop);
2823 vdup();
2824 vtop[-1].r = r; /* save register value */
2825 vtop->r = vtop[-1].r2;
2827 /* allocate second register */
2828 rc2 = RC_INT;
2829 if (rc == RC_IRET)
2830 rc2 = RC_LRET;
2831 r2 = get_reg(rc2);
2832 load(r2, vtop);
2833 vpop();
2834 /* write second register */
2835 vtop->r2 = r2;
2836 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
2837 int t1, t;
2838 /* lvalue of scalar type : need to use lvalue type
2839 because of possible cast */
2840 t = vtop->t;
2841 t1 = t;
2842 /* compute memory access type */
2843 if (vtop->r & VT_LVAL_BYTE)
2844 t = VT_BYTE;
2845 else if (vtop->r & VT_LVAL_SHORT)
2846 t = VT_SHORT;
2847 if (vtop->r & VT_LVAL_UNSIGNED)
2848 t |= VT_UNSIGNED;
2849 vtop->t = t;
2850 load(r, vtop);
2851 /* restore wanted type */
2852 vtop->t = t1;
2853 } else {
2854 /* one register type load */
2855 load(r, vtop);
2858 vtop->r = r;
2860 return r;
2863 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2864 void gv2(int rc1, int rc2)
2866 /* generate more generic register first */
2867 if (rc1 <= rc2) {
2868 vswap();
2869 gv(rc1);
2870 vswap();
2871 gv(rc2);
2872 /* test if reload is needed for first register */
2873 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2874 vswap();
2875 gv(rc1);
2876 vswap();
2878 } else {
2879 gv(rc2);
2880 vswap();
2881 gv(rc1);
2882 vswap();
2883 /* test if reload is needed for first register */
2884 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
2885 gv(rc2);
2890 /* expand long long on stack in two int registers */
2891 void lexpand(void)
2893 int u;
2895 u = vtop->t & VT_UNSIGNED;
2896 gv(RC_INT);
2897 vdup();
2898 vtop[0].r = vtop[-1].r2;
2899 vtop[0].r2 = VT_CONST;
2900 vtop[-1].r2 = VT_CONST;
2901 vtop[0].t = VT_INT | u;
2902 vtop[-1].t = VT_INT | u;
2905 /* build a long long from two ints */
2906 void lbuild(int t)
2908 gv2(RC_INT, RC_INT);
2909 vtop[-1].r2 = vtop[0].r;
2910 vtop[-1].t = t;
2911 vpop();
2914 /* rotate n first stack elements to the bottom */
2915 void vrotb(int n)
2917 int i;
2918 SValue tmp;
2920 tmp = vtop[-n + 1];
2921 for(i=-n+1;i!=0;i++)
2922 vtop[i] = vtop[i+1];
2923 vtop[0] = tmp;
2926 /* pop stack value */
2927 void vpop(void)
2929 int v;
2930 v = vtop->r & VT_VALMASK;
2931 #ifdef TCC_TARGET_I386
2932 /* for x86, we need to pop the FP stack */
2933 if (v == REG_ST0) {
2934 o(0xd9dd); /* fstp %st(1) */
2935 } else
2936 #endif
2937 if (v == VT_JMP || v == VT_JMPI) {
2938 /* need to put correct jump if && or || without test */
2939 gsym(vtop->c.ul);
2941 vtop--;
2944 /* convert stack entry to register and duplicate its value in another
2945 register */
2946 void gv_dup(void)
2948 int rc, t, r, r1;
2949 SValue sv;
2951 t = vtop->t;
2952 if ((t & VT_BTYPE) == VT_LLONG) {
2953 lexpand();
2954 gv_dup();
2955 vswap();
2956 vrotb(3);
2957 gv_dup();
2958 vrotb(4);
2959 /* stack: H L L1 H1 */
2960 lbuild(t);
2961 vrotb(3);
2962 vrotb(3);
2963 vswap();
2964 lbuild(t);
2965 vswap();
2966 } else {
2967 /* duplicate value */
2968 rc = RC_INT;
2969 sv.t = VT_INT;
2970 if (is_float(t)) {
2971 rc = RC_FLOAT;
2972 sv.t = t;
2974 r = gv(rc);
2975 r1 = get_reg(rc);
2976 sv.r = r;
2977 sv.c.ul = 0;
2978 load(r1, &sv); /* move r to r1 */
2979 vdup();
2980 /* duplicates value */
2981 vtop->r = r1;
2985 /* generate CPU independent (unsigned) long long operations */
2986 void gen_opl(int op)
2988 int t, a, b, op1, c, i;
2989 int func;
2990 GFuncContext gf;
2991 SValue tmp;
2993 switch(op) {
2994 case '/':
2995 case TOK_PDIV:
2996 func = TOK___divdi3;
2997 goto gen_func;
2998 case TOK_UDIV:
2999 func = TOK___udivdi3;
3000 goto gen_func;
3001 case '%':
3002 func = TOK___moddi3;
3003 goto gen_func;
3004 case TOK_UMOD:
3005 func = TOK___umoddi3;
3006 gen_func:
3007 /* call generic long long function */
3008 gfunc_start(&gf, FUNC_CDECL);
3009 gfunc_param(&gf);
3010 gfunc_param(&gf);
3011 vpush_sym(func_old_type, func);
3012 gfunc_call(&gf);
3013 vpushi(0);
3014 vtop->r = REG_IRET;
3015 vtop->r2 = REG_LRET;
3016 break;
3017 case '^':
3018 case '&':
3019 case '|':
3020 case '*':
3021 case '+':
3022 case '-':
3023 t = vtop->t;
3024 vswap();
3025 lexpand();
3026 vrotb(3);
3027 lexpand();
3028 /* stack: L1 H1 L2 H2 */
3029 tmp = vtop[0];
3030 vtop[0] = vtop[-3];
3031 vtop[-3] = tmp;
3032 tmp = vtop[-2];
3033 vtop[-2] = vtop[-3];
3034 vtop[-3] = tmp;
3035 vswap();
3036 /* stack: H1 H2 L1 L2 */
3037 if (op == '*') {
3038 vpushv(vtop - 1);
3039 vpushv(vtop - 1);
3040 gen_op(TOK_UMULL);
3041 lexpand();
3042 /* stack: H1 H2 L1 L2 ML MH */
3043 for(i=0;i<4;i++)
3044 vrotb(6);
3045 /* stack: ML MH H1 H2 L1 L2 */
3046 tmp = vtop[0];
3047 vtop[0] = vtop[-2];
3048 vtop[-2] = tmp;
3049 /* stack: ML MH H1 L2 H2 L1 */
3050 gen_op('*');
3051 vrotb(3);
3052 vrotb(3);
3053 gen_op('*');
3054 /* stack: ML MH M1 M2 */
3055 gen_op('+');
3056 gen_op('+');
3057 } else if (op == '+' || op == '-') {
3058 /* XXX: add non carry method too (for MIPS or alpha) */
3059 if (op == '+')
3060 op1 = TOK_ADDC1;
3061 else
3062 op1 = TOK_SUBC1;
3063 gen_op(op1);
3064 /* stack: H1 H2 (L1 op L2) */
3065 vrotb(3);
3066 vrotb(3);
3067 gen_op(op1 + 1); /* TOK_xxxC2 */
3068 } else {
3069 gen_op(op);
3070 /* stack: H1 H2 (L1 op L2) */
3071 vrotb(3);
3072 vrotb(3);
3073 /* stack: (L1 op L2) H1 H2 */
3074 gen_op(op);
3075 /* stack: (L1 op L2) (H1 op H2) */
3077 /* stack: L H */
3078 lbuild(t);
3079 break;
3080 case TOK_SAR:
3081 case TOK_SHR:
3082 case TOK_SHL:
3083 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3084 t = vtop[-1].t;
3085 vswap();
3086 lexpand();
3087 vrotb(3);
3088 /* stack: L H shift */
3089 c = (int)vtop->c.i;
3090 /* constant: simpler */
3091 /* NOTE: all comments are for SHL. the other cases are
3092 done by swaping words */
3093 vpop();
3094 if (op != TOK_SHL)
3095 vswap();
3096 if (c >= 32) {
3097 /* stack: L H */
3098 vpop();
3099 if (c > 32) {
3100 vpushi(c - 32);
3101 gen_op(op);
3103 if (op != TOK_SAR) {
3104 vpushi(0);
3105 } else {
3106 gv_dup();
3107 vpushi(31);
3108 gen_op(TOK_SAR);
3110 vswap();
3111 } else {
3112 vswap();
3113 gv_dup();
3114 /* stack: H L L */
3115 vpushi(c);
3116 gen_op(op);
3117 vswap();
3118 vpushi(32 - c);
3119 if (op == TOK_SHL)
3120 gen_op(TOK_SHR);
3121 else
3122 gen_op(TOK_SHL);
3123 vrotb(3);
3124 /* stack: L L H */
3125 vpushi(c);
3126 gen_op(op);
3127 gen_op('|');
3129 if (op != TOK_SHL)
3130 vswap();
3131 lbuild(t);
3132 } else {
3133 /* XXX: should provide a faster fallback on x86 ? */
3134 switch(op) {
3135 case TOK_SAR:
3136 func = TOK___sardi3;
3137 goto gen_func;
3138 case TOK_SHR:
3139 func = TOK___shrdi3;
3140 goto gen_func;
3141 case TOK_SHL:
3142 func = TOK___shldi3;
3143 goto gen_func;
3146 break;
3147 default:
3148 /* compare operations */
3149 t = vtop->t;
3150 vswap();
3151 lexpand();
3152 vrotb(3);
3153 lexpand();
3154 /* stack: L1 H1 L2 H2 */
3155 tmp = vtop[-1];
3156 vtop[-1] = vtop[-2];
3157 vtop[-2] = tmp;
3158 /* stack: L1 L2 H1 H2 */
3159 /* compare high */
3160 op1 = op;
3161 /* when values are equal, we need to compare low words. since
3162 the jump is inverted, we invert the test too. */
3163 if (op1 == TOK_LT)
3164 op1 = TOK_LE;
3165 else if (op1 == TOK_GT)
3166 op1 = TOK_GE;
3167 else if (op1 == TOK_ULT)
3168 op1 = TOK_ULE;
3169 else if (op1 == TOK_UGT)
3170 op1 = TOK_UGE;
3171 a = 0;
3172 b = 0;
3173 gen_op(op1);
3174 if (op1 != TOK_NE) {
3175 a = gtst(1, 0);
3177 if (op != TOK_EQ) {
3178 /* generate non equal test */
3179 /* XXX: NOT PORTABLE yet */
3180 if (a == 0) {
3181 b = gtst(0, 0);
3182 } else {
3183 #ifdef TCC_TARGET_I386
3184 b = psym(0x850f, 0);
3185 #else
3186 error("not implemented");
3187 #endif
3190 /* compare low */
3191 gen_op(op);
3192 a = gtst(1, a);
3193 gsym(b);
3194 vset(VT_INT, VT_JMPI, a);
3195 break;
3199 /* handle integer constant optimizations and various machine
3200 independant opt */
3201 void gen_opic(int op)
3203 int fc, c1, c2, n;
3204 SValue *v1, *v2;
3206 v1 = vtop - 1;
3207 v2 = vtop;
3208 /* currently, we cannot do computations with forward symbols */
3209 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3210 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3211 if (c1 && c2) {
3212 fc = v2->c.i;
3213 switch(op) {
3214 case '+': v1->c.i += fc; break;
3215 case '-': v1->c.i -= fc; break;
3216 case '&': v1->c.i &= fc; break;
3217 case '^': v1->c.i ^= fc; break;
3218 case '|': v1->c.i |= fc; break;
3219 case '*': v1->c.i *= fc; break;
3221 case TOK_PDIV:
3222 case '/':
3223 case '%':
3224 case TOK_UDIV:
3225 case TOK_UMOD:
3226 /* if division by zero, generate explicit division */
3227 if (fc == 0) {
3228 if (const_wanted)
3229 error("division by zero in constant");
3230 goto general_case;
3232 switch(op) {
3233 default: v1->c.i /= fc; break;
3234 case '%': v1->c.i %= fc; break;
3235 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3236 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3238 break;
3239 case TOK_SHL: v1->c.i <<= fc; break;
3240 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3241 case TOK_SAR: v1->c.i >>= fc; break;
3242 /* tests */
3243 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3244 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3245 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3246 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3247 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3248 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3249 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3250 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3251 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3252 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3253 /* logical */
3254 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3255 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3256 default:
3257 goto general_case;
3259 vtop--;
3260 } else {
3261 /* if commutative ops, put c2 as constant */
3262 if (c1 && (op == '+' || op == '&' || op == '^' ||
3263 op == '|' || op == '*')) {
3264 vswap();
3265 swap(&c1, &c2);
3267 fc = vtop->c.i;
3268 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3269 op == TOK_PDIV) &&
3270 fc == 1) ||
3271 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3272 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3273 fc == 0) ||
3274 (op == '&' &&
3275 fc == -1))) {
3276 /* nothing to do */
3277 vtop--;
3278 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3279 /* try to use shifts instead of muls or divs */
3280 if (fc > 0 && (fc & (fc - 1)) == 0) {
3281 n = -1;
3282 while (fc) {
3283 fc >>= 1;
3284 n++;
3286 vtop->c.i = n;
3287 if (op == '*')
3288 op = TOK_SHL;
3289 else if (op == TOK_PDIV)
3290 op = TOK_SAR;
3291 else
3292 op = TOK_SHR;
3294 goto general_case;
3295 } else {
3296 general_case:
3297 /* call low level op generator */
3298 gen_opi(op);
3303 /* generate a floating point operation with constant propagation */
3304 void gen_opif(int op)
3306 int c1, c2;
3307 SValue *v1, *v2;
3308 long double f1, f2;
3310 v1 = vtop - 1;
3311 v2 = vtop;
3312 /* currently, we cannot do computations with forward symbols */
3313 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3314 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3315 if (c1 && c2) {
3316 if (v1->t == VT_FLOAT) {
3317 f1 = v1->c.f;
3318 f2 = v2->c.f;
3319 } else if (v1->t == VT_DOUBLE) {
3320 f1 = v1->c.d;
3321 f2 = v2->c.d;
3322 } else {
3323 f1 = v1->c.ld;
3324 f2 = v2->c.ld;
3327 /* NOTE: we only do constant propagation if finite number (not
3328 NaN or infinity) (ANSI spec) */
3329 if (!ieee_finite(f1) || !ieee_finite(f2))
3330 goto general_case;
3332 switch(op) {
3333 case '+': f1 += f2; break;
3334 case '-': f1 -= f2; break;
3335 case '*': f1 *= f2; break;
3336 case '/':
3337 if (f2 == 0.0) {
3338 if (const_wanted)
3339 error("division by zero in constant");
3340 goto general_case;
3342 f1 /= f2;
3343 break;
3344 /* XXX: also handles tests ? */
3345 default:
3346 goto general_case;
3348 /* XXX: overflow test ? */
3349 if (v1->t == VT_FLOAT) {
3350 v1->c.f = f1;
3351 } else if (v1->t == VT_DOUBLE) {
3352 v1->c.d = f1;
3353 } else {
3354 v1->c.ld = f1;
3356 vtop--;
3357 } else {
3358 general_case:
3359 gen_opf(op);
3364 int pointed_size(int t)
3366 return type_size(pointed_type(t), &t);
3369 #if 0
3370 void check_pointer_types(SValue *p1, SValue *p2)
3372 char buf1[256], buf2[256];
3373 int t1, t2;
3374 t1 = p1->t;
3375 t2 = p2->t;
3376 if (!is_compatible_types(t1, t2)) {
3377 type_to_str(buf1, sizeof(buf1), t1, NULL);
3378 type_to_str(buf2, sizeof(buf2), t2, NULL);
3379 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3382 #endif
3384 /* generic gen_op: handles types problems */
3385 void gen_op(int op)
3387 int u, t1, t2, bt1, bt2, t;
3389 t1 = vtop[-1].t;
3390 t2 = vtop[0].t;
3391 bt1 = t1 & VT_BTYPE;
3392 bt2 = t2 & VT_BTYPE;
3394 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3395 /* at least one operand is a pointer */
3396 /* relationnal op: must be both pointers */
3397 if (op >= TOK_ULT && op <= TOK_GT) {
3398 // check_pointer_types(vtop, vtop - 1);
3399 /* pointers are handled are unsigned */
3400 t = VT_INT | VT_UNSIGNED;
3401 goto std_op;
3403 /* if both pointers, then it must be the '-' op */
3404 if ((t1 & VT_BTYPE) == VT_PTR &&
3405 (t2 & VT_BTYPE) == VT_PTR) {
3406 if (op != '-')
3407 error("cannot use pointers here");
3408 // check_pointer_types(vtop - 1, vtop);
3409 /* XXX: check that types are compatible */
3410 u = pointed_size(t1);
3411 gen_opic(op);
3412 /* set to integer type */
3413 vtop->t = VT_INT;
3414 vpushi(u);
3415 gen_op(TOK_PDIV);
3416 } else {
3417 /* exactly one pointer : must be '+' or '-'. */
3418 if (op != '-' && op != '+')
3419 error("cannot use pointers here");
3420 /* Put pointer as first operand */
3421 if ((t2 & VT_BTYPE) == VT_PTR) {
3422 vswap();
3423 swap(&t1, &t2);
3425 /* XXX: cast to int ? (long long case) */
3426 vpushi(pointed_size(vtop[-1].t));
3427 gen_op('*');
3428 #ifdef CONFIG_TCC_BCHECK
3429 /* if evaluating constant expression, no code should be
3430 generated, so no bound check */
3431 if (do_bounds_check && !const_wanted) {
3432 /* if bounded pointers, we generate a special code to
3433 test bounds */
3434 if (op == '-') {
3435 vpushi(0);
3436 vswap();
3437 gen_op('-');
3439 gen_bounded_ptr_add();
3440 } else
3441 #endif
3443 gen_opic(op);
3445 /* put again type if gen_opic() swaped operands */
3446 vtop->t = t1;
3448 } else if (is_float(bt1) || is_float(bt2)) {
3449 /* compute bigger type and do implicit casts */
3450 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3451 t = VT_LDOUBLE;
3452 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3453 t = VT_DOUBLE;
3454 } else {
3455 t = VT_FLOAT;
3457 /* floats can only be used for a few operations */
3458 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3459 (op < TOK_ULT || op > TOK_GT))
3460 error("invalid operands for binary operation");
3461 goto std_op;
3462 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3463 /* cast to biggest op */
3464 t = VT_LLONG;
3465 /* convert to unsigned if it does not fit in a long long */
3466 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3467 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3468 t |= VT_UNSIGNED;
3469 goto std_op;
3470 } else {
3471 /* integer operations */
3472 t = VT_INT;
3473 /* convert to unsigned if it does not fit in an integer */
3474 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3475 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3476 t |= VT_UNSIGNED;
3477 std_op:
3478 /* XXX: currently, some unsigned operations are explicit, so
3479 we modify them here */
3480 if (t & VT_UNSIGNED) {
3481 if (op == TOK_SAR)
3482 op = TOK_SHR;
3483 else if (op == '/')
3484 op = TOK_UDIV;
3485 else if (op == '%')
3486 op = TOK_UMOD;
3487 else if (op == TOK_LT)
3488 op = TOK_ULT;
3489 else if (op == TOK_GT)
3490 op = TOK_UGT;
3491 else if (op == TOK_LE)
3492 op = TOK_ULE;
3493 else if (op == TOK_GE)
3494 op = TOK_UGE;
3496 vswap();
3497 gen_cast(t);
3498 vswap();
3499 /* special case for shifts and long long: we keep the shift as
3500 an integer */
3501 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3502 gen_cast(VT_INT);
3503 else
3504 gen_cast(t);
3505 if (is_float(t))
3506 gen_opif(op);
3507 else if ((t & VT_BTYPE) == VT_LLONG)
3508 gen_opl(op);
3509 else
3510 gen_opic(op);
3511 if (op >= TOK_ULT && op <= TOK_GT) {
3512 /* relationnal op: the result is an int */
3513 vtop->t = VT_INT;
3514 } else {
3515 vtop->t = t;
3520 /* generic itof for unsigned long long case */
3521 void gen_cvt_itof1(int t)
3523 GFuncContext gf;
3525 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3526 (VT_LLONG | VT_UNSIGNED)) {
3528 gfunc_start(&gf, FUNC_CDECL);
3529 gfunc_param(&gf);
3530 if (t == VT_FLOAT)
3531 vpush_sym(func_old_type, TOK___ulltof);
3532 else if (t == VT_DOUBLE)
3533 vpush_sym(func_old_type, TOK___ulltod);
3534 else
3535 vpush_sym(func_old_type, TOK___ulltold);
3536 gfunc_call(&gf);
3537 vpushi(0);
3538 vtop->r = REG_FRET;
3539 } else {
3540 gen_cvt_itof(t);
3544 /* generic ftoi for unsigned long long case */
3545 void gen_cvt_ftoi1(int t)
3547 GFuncContext gf;
3548 int st;
3550 if (t == (VT_LLONG | VT_UNSIGNED)) {
3551 /* not handled natively */
3552 gfunc_start(&gf, FUNC_CDECL);
3553 st = vtop->t & VT_BTYPE;
3554 gfunc_param(&gf);
3555 if (st == VT_FLOAT)
3556 vpush_sym(func_old_type, TOK___fixunssfdi);
3557 else if (st == VT_DOUBLE)
3558 vpush_sym(func_old_type, TOK___fixunsdfdi);
3559 else
3560 vpush_sym(func_old_type, TOK___fixunsxfdi);
3561 gfunc_call(&gf);
3562 vpushi(0);
3563 vtop->r = REG_IRET;
3564 vtop->r2 = REG_LRET;
3565 } else {
3566 gen_cvt_ftoi(t);
3570 /* force char or short cast */
3571 void force_charshort_cast(int t)
3573 int bits, dbt;
3574 dbt = t & VT_BTYPE;
3575 /* XXX: add optimization if lvalue : just change type and offset */
3576 if (dbt == VT_BYTE)
3577 bits = 8;
3578 else
3579 bits = 16;
3580 if (t & VT_UNSIGNED) {
3581 vpushi((1 << bits) - 1);
3582 gen_op('&');
3583 } else {
3584 bits = 32 - bits;
3585 vpushi(bits);
3586 gen_op(TOK_SHL);
3587 vpushi(bits);
3588 gen_op(TOK_SAR);
3592 /* cast 'vtop' to 't' type */
3593 void gen_cast(int t)
3595 int sbt, dbt, sf, df, c;
3597 /* special delayed cast for char/short */
3598 /* XXX: in some cases (multiple cascaded casts), it may still
3599 be incorrect */
3600 if (vtop->r & VT_MUSTCAST) {
3601 vtop->r &= ~VT_MUSTCAST;
3602 force_charshort_cast(vtop->t);
3605 dbt = t & (VT_BTYPE | VT_UNSIGNED);
3606 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
3608 if (sbt != dbt) {
3609 sf = is_float(sbt);
3610 df = is_float(dbt);
3611 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3612 if (sf && df) {
3613 /* convert from fp to fp */
3614 if (c) {
3615 /* constant case: we can do it now */
3616 /* XXX: in ISOC, cannot do it if error in convert */
3617 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
3618 vtop->c.f = (float)vtop->c.d;
3619 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
3620 vtop->c.f = (float)vtop->c.ld;
3621 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
3622 vtop->c.d = (double)vtop->c.f;
3623 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
3624 vtop->c.d = (double)vtop->c.ld;
3625 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
3626 vtop->c.ld = (long double)vtop->c.f;
3627 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
3628 vtop->c.ld = (long double)vtop->c.d;
3629 } else {
3630 /* non constant case: generate code */
3631 gen_cvt_ftof(dbt);
3633 } else if (df) {
3634 /* convert int to fp */
3635 if (c) {
3636 switch(sbt) {
3637 case VT_LLONG | VT_UNSIGNED:
3638 case VT_LLONG:
3639 /* XXX: add const cases for long long */
3640 goto do_itof;
3641 case VT_INT | VT_UNSIGNED:
3642 switch(dbt) {
3643 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
3644 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
3645 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
3647 break;
3648 default:
3649 switch(dbt) {
3650 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
3651 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
3652 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
3654 break;
3656 } else {
3657 do_itof:
3658 gen_cvt_itof1(dbt);
3660 } else if (sf) {
3661 /* convert fp to int */
3662 /* we handle char/short/etc... with generic code */
3663 if (dbt != (VT_INT | VT_UNSIGNED) &&
3664 dbt != (VT_LLONG | VT_UNSIGNED) &&
3665 dbt != VT_LLONG)
3666 dbt = VT_INT;
3667 if (c) {
3668 switch(dbt) {
3669 case VT_LLONG | VT_UNSIGNED:
3670 case VT_LLONG:
3671 /* XXX: add const cases for long long */
3672 goto do_ftoi;
3673 case VT_INT | VT_UNSIGNED:
3674 switch(sbt) {
3675 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
3676 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3677 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
3679 break;
3680 default:
3681 /* int case */
3682 switch(sbt) {
3683 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
3684 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
3685 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
3687 break;
3689 } else {
3690 do_ftoi:
3691 gen_cvt_ftoi1(dbt);
3693 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
3694 /* additionnal cast for char/short/bool... */
3695 vtop->t = dbt;
3696 gen_cast(t);
3698 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
3699 if ((sbt & VT_BTYPE) != VT_LLONG) {
3700 /* scalar to long long */
3701 if (c) {
3702 if (sbt == (VT_INT | VT_UNSIGNED))
3703 vtop->c.ll = vtop->c.ui;
3704 else
3705 vtop->c.ll = vtop->c.i;
3706 } else {
3707 /* machine independant conversion */
3708 gv(RC_INT);
3709 /* generate high word */
3710 if (sbt == (VT_INT | VT_UNSIGNED)) {
3711 vpushi(0);
3712 gv(RC_INT);
3713 } else {
3714 gv_dup();
3715 vpushi(31);
3716 gen_op(TOK_SAR);
3718 /* patch second register */
3719 vtop[-1].r2 = vtop->r;
3720 vpop();
3723 } else if (dbt == VT_BOOL) {
3724 /* scalar to bool */
3725 vpushi(0);
3726 gen_op(TOK_NE);
3727 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
3728 (dbt & VT_BTYPE) == VT_SHORT) {
3729 force_charshort_cast(t);
3730 } else if ((dbt & VT_BTYPE) == VT_INT) {
3731 /* scalar to int */
3732 if (sbt == VT_LLONG) {
3733 /* from long long: just take low order word */
3734 lexpand();
3735 vpop();
3737 /* if lvalue and single word type, nothing to do because
3738 the lvalue already contains the real type size (see
3739 VT_LVAL_xxx constants) */
3742 vtop->t = t;
3745 /* return type size. Put alignment at 'a' */
3746 int type_size(int t, int *a)
3748 Sym *s;
3749 int bt;
3751 bt = t & VT_BTYPE;
3752 if (bt == VT_STRUCT) {
3753 /* struct/union */
3754 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3755 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
3756 return s->c;
3757 } else if (bt == VT_PTR) {
3758 if (t & VT_ARRAY) {
3759 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3760 return type_size(s->t, a) * s->c;
3761 } else {
3762 *a = PTR_SIZE;
3763 return PTR_SIZE;
3765 } else if (bt == VT_LDOUBLE) {
3766 *a = LDOUBLE_ALIGN;
3767 return LDOUBLE_SIZE;
3768 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3769 *a = 8;
3770 return 8;
3771 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
3772 *a = 4;
3773 return 4;
3774 } else if (bt == VT_SHORT) {
3775 *a = 2;
3776 return 2;
3777 } else {
3778 /* char, void, function, _Bool */
3779 *a = 1;
3780 return 1;
3784 /* return the pointed type of t */
3785 int pointed_type(int t)
3787 Sym *s;
3788 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
3789 return s->t | (t & ~VT_TYPE);
3792 int mk_pointer(int t)
3794 int p;
3795 p = anon_sym++;
3796 sym_push(p, t, 0, -1);
3797 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
3800 int is_compatible_types(int t1, int t2)
3802 Sym *s1, *s2;
3803 int bt1, bt2;
3805 t1 &= VT_TYPE;
3806 t2 &= VT_TYPE;
3807 bt1 = t1 & VT_BTYPE;
3808 bt2 = t2 & VT_BTYPE;
3809 if (bt1 == VT_PTR) {
3810 t1 = pointed_type(t1);
3811 /* if function, then convert implicitely to function pointer */
3812 if (bt2 != VT_FUNC) {
3813 if (bt2 != VT_PTR)
3814 return 0;
3815 t2 = pointed_type(t2);
3817 /* void matches everything */
3818 t1 &= VT_TYPE;
3819 t2 &= VT_TYPE;
3820 if (t1 == VT_VOID || t2 == VT_VOID)
3821 return 1;
3822 return is_compatible_types(t1, t2);
3823 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
3824 return (t2 == t1);
3825 } else if (bt1 == VT_FUNC) {
3826 if (bt2 != VT_FUNC)
3827 return 0;
3828 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
3829 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
3830 if (!is_compatible_types(s1->t, s2->t))
3831 return 0;
3832 /* XXX: not complete */
3833 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
3834 return 1;
3835 if (s1->c != s2->c)
3836 return 0;
3837 while (s1 != NULL) {
3838 if (s2 == NULL)
3839 return 0;
3840 if (!is_compatible_types(s1->t, s2->t))
3841 return 0;
3842 s1 = s1->next;
3843 s2 = s2->next;
3845 if (s2)
3846 return 0;
3847 return 1;
3848 } else {
3849 /* XXX: not complete */
3850 return 1;
3854 /* print a type. If 'varstr' is not NULL, then the variable is also
3855 printed in the type */
3856 /* XXX: union */
3857 /* XXX: add array and function pointers */
3858 void type_to_str(char *buf, int buf_size,
3859 int t, const char *varstr)
3861 int bt, v;
3862 Sym *s, *sa;
3863 char buf1[256];
3864 const char *tstr;
3866 t = t & VT_TYPE;
3867 bt = t & VT_BTYPE;
3868 buf[0] = '\0';
3869 if (t & VT_UNSIGNED)
3870 pstrcat(buf, buf_size, "unsigned ");
3871 switch(bt) {
3872 case VT_VOID:
3873 tstr = "void";
3874 goto add_tstr;
3875 case VT_BOOL:
3876 tstr = "_Bool";
3877 goto add_tstr;
3878 case VT_BYTE:
3879 tstr = "char";
3880 goto add_tstr;
3881 case VT_SHORT:
3882 tstr = "short";
3883 goto add_tstr;
3884 case VT_INT:
3885 tstr = "int";
3886 goto add_tstr;
3887 case VT_LONG:
3888 tstr = "long";
3889 goto add_tstr;
3890 case VT_LLONG:
3891 tstr = "long long";
3892 goto add_tstr;
3893 case VT_FLOAT:
3894 tstr = "float";
3895 goto add_tstr;
3896 case VT_DOUBLE:
3897 tstr = "double";
3898 goto add_tstr;
3899 case VT_LDOUBLE:
3900 tstr = "long double";
3901 add_tstr:
3902 pstrcat(buf, buf_size, tstr);
3903 break;
3904 case VT_ENUM:
3905 case VT_STRUCT:
3906 if (bt == VT_STRUCT)
3907 tstr = "struct ";
3908 else
3909 tstr = "enum ";
3910 pstrcat(buf, buf_size, tstr);
3911 v = (unsigned)t >> VT_STRUCT_SHIFT;
3912 if (v >= SYM_FIRST_ANOM)
3913 pstrcat(buf, buf_size, "<anonymous>");
3914 else
3915 pstrcat(buf, buf_size, get_tok_str(v, NULL));
3916 break;
3917 case VT_FUNC:
3918 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3919 type_to_str(buf, buf_size, s->t, varstr);
3920 pstrcat(buf, buf_size, "(");
3921 sa = s->next;
3922 while (sa != NULL) {
3923 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
3924 pstrcat(buf, buf_size, buf1);
3925 sa = sa->next;
3926 if (sa)
3927 pstrcat(buf, buf_size, ", ");
3929 pstrcat(buf, buf_size, ")");
3930 goto no_var;
3931 case VT_PTR:
3932 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
3933 pstrcpy(buf1, sizeof(buf1), "*");
3934 if (varstr)
3935 pstrcat(buf1, sizeof(buf1), varstr);
3936 type_to_str(buf, buf_size, s->t, buf1);
3937 goto no_var;
3939 if (varstr) {
3940 pstrcat(buf, buf_size, " ");
3941 pstrcat(buf, buf_size, varstr);
3943 no_var: ;
3946 /* verify type compatibility to store vtop in 'dt' type, and generate
3947 casts if needed. */
3948 void gen_assign_cast(int dt)
3950 int st;
3951 char buf1[256], buf2[256];
3953 st = vtop->t; /* source type */
3954 if ((dt & VT_BTYPE) == VT_PTR) {
3955 /* special cases for pointers */
3956 /* a function is implicitely a function pointer */
3957 if ((st & VT_BTYPE) == VT_FUNC) {
3958 if (!is_compatible_types(pointed_type(dt), st))
3959 goto error;
3960 else
3961 goto type_ok;
3963 /* '0' can also be a pointer */
3964 if ((st & VT_BTYPE) == VT_INT &&
3965 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
3966 vtop->c.i == 0)
3967 goto type_ok;
3969 if (!is_compatible_types(dt, st)) {
3970 error:
3971 type_to_str(buf1, sizeof(buf1), st, NULL);
3972 type_to_str(buf2, sizeof(buf2), dt, NULL);
3973 error("cannot cast '%s' to '%s'", buf1, buf2);
3975 type_ok:
3976 gen_cast(dt);
3979 /* store vtop in lvalue pushed on stack */
3980 void vstore(void)
3982 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
3983 GFuncContext gf;
3985 ft = vtop[-1].t;
3986 sbt = vtop->t & VT_BTYPE;
3987 dbt = ft & VT_BTYPE;
3988 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
3989 (sbt == VT_INT && dbt == VT_SHORT)) {
3990 /* optimize char/short casts */
3991 delayed_cast = VT_MUSTCAST;
3992 vtop->t = ft & VT_TYPE;
3993 } else {
3994 delayed_cast = 0;
3995 gen_assign_cast(ft & VT_TYPE);
3998 if (sbt == VT_STRUCT) {
3999 /* if structure, only generate pointer */
4000 /* structure assignment : generate memcpy */
4001 /* XXX: optimize if small size */
4002 vdup();
4003 gfunc_start(&gf, FUNC_CDECL);
4004 /* type size */
4005 size = type_size(vtop->t, &align);
4006 vpushi(size);
4007 gfunc_param(&gf);
4008 /* source */
4009 vtop->t = VT_INT;
4010 gaddrof();
4011 gfunc_param(&gf);
4012 /* destination */
4013 vswap();
4014 vtop->t = VT_INT;
4015 gaddrof();
4016 gfunc_param(&gf);
4018 save_regs(0);
4019 vpush_sym(func_old_type, TOK_memcpy);
4020 gfunc_call(&gf);
4021 /* leave source on stack */
4022 } else if (ft & VT_BITFIELD) {
4023 /* bitfield store handling */
4024 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4025 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4026 /* remove bit field info to avoid loops */
4027 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4029 /* duplicate destination */
4030 vdup();
4031 vtop[-1] = vtop[-2];
4033 /* mask and shift source */
4034 vpushi((1 << bit_size) - 1);
4035 gen_op('&');
4036 vpushi(bit_pos);
4037 gen_op(TOK_SHL);
4038 /* load destination, mask and or with source */
4039 vswap();
4040 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4041 gen_op('&');
4042 gen_op('|');
4043 /* store result */
4044 vstore();
4045 } else {
4046 #ifdef CONFIG_TCC_BCHECK
4047 /* bound check case */
4048 if (vtop[-1].r & VT_MUSTBOUND) {
4049 vswap();
4050 gbound();
4051 vswap();
4053 #endif
4054 rc = RC_INT;
4055 if (is_float(ft))
4056 rc = RC_FLOAT;
4057 r = gv(rc); /* generate value */
4058 /* if lvalue was saved on stack, must read it */
4059 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4060 SValue sv;
4061 t = get_reg(RC_INT);
4062 sv.t = VT_INT;
4063 sv.r = VT_LOCAL | VT_LVAL;
4064 sv.c.ul = vtop[-1].c.ul;
4065 load(t, &sv);
4066 vtop[-1].r = t | VT_LVAL;
4068 store(r, vtop - 1);
4069 /* two word case handling : store second register at word + 4 */
4070 if ((ft & VT_BTYPE) == VT_LLONG) {
4071 vswap();
4072 /* convert to int to increment easily */
4073 vtop->t = VT_INT;
4074 gaddrof();
4075 vpushi(4);
4076 gen_op('+');
4077 vtop->r |= VT_LVAL;
4078 vswap();
4079 /* XXX: it works because r2 is spilled last ! */
4080 store(vtop->r2, vtop - 1);
4082 vswap();
4083 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4084 vtop->r |= delayed_cast;
4088 /* post defines POST/PRE add. c is the token ++ or -- */
4089 void inc(int post, int c)
4091 test_lvalue();
4092 vdup(); /* save lvalue */
4093 if (post) {
4094 gv_dup(); /* duplicate value */
4095 vrotb(3);
4096 vrotb(3);
4098 /* add constant */
4099 vpushi(c - TOK_MID);
4100 gen_op('+');
4101 vstore(); /* store value */
4102 if (post)
4103 vpop(); /* if post op, return saved value */
4106 /* Parse GNUC __attribute__ extension. Currently, the following
4107 extensions are recognized:
4108 - aligned(n) : set data/function alignment.
4109 - section(x) : generate data/code in this section.
4110 - unused : currently ignored, but may be used someday.
4112 void parse_attribute(AttributeDef *ad)
4114 int t, n;
4116 next();
4117 skip('(');
4118 skip('(');
4119 while (tok != ')') {
4120 if (tok < TOK_IDENT)
4121 expect("attribute name");
4122 t = tok;
4123 next();
4124 switch(t) {
4125 case TOK_SECTION:
4126 case TOK___SECTION__:
4127 skip('(');
4128 if (tok != TOK_STR)
4129 expect("section name");
4130 ad->section = find_section(tokc.ts->str);
4131 next();
4132 skip(')');
4133 break;
4134 case TOK_ALIGNED:
4135 case TOK___ALIGNED__:
4136 skip('(');
4137 n = expr_const();
4138 if (n <= 0 || (n & (n - 1)) != 0)
4139 error("alignment must be a positive power of two");
4140 ad->aligned = n;
4141 skip(')');
4142 break;
4143 case TOK_UNUSED:
4144 case TOK___UNUSED__:
4145 /* currently, no need to handle it because tcc does not
4146 track unused objects */
4147 break;
4148 case TOK_NORETURN:
4149 case TOK___NORETURN__:
4150 /* currently, no need to handle it because tcc does not
4151 track unused objects */
4152 break;
4153 case TOK_CDECL:
4154 case TOK___CDECL:
4155 case TOK___CDECL__:
4156 ad->func_call = FUNC_CDECL;
4157 break;
4158 case TOK_STDCALL:
4159 case TOK___STDCALL:
4160 case TOK___STDCALL__:
4161 ad->func_call = FUNC_STDCALL;
4162 break;
4163 default:
4164 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4165 /* skip parameters */
4166 /* XXX: skip parenthesis too */
4167 if (tok == '(') {
4168 next();
4169 while (tok != ')' && tok != -1)
4170 next();
4171 next();
4173 break;
4175 if (tok != ',')
4176 break;
4177 next();
4179 skip(')');
4180 skip(')');
4183 /* enum/struct/union declaration */
4184 int struct_decl(int u)
4186 int a, t, b, v, size, align, maxalign, c, offset;
4187 int bit_size, bit_pos, bsize, bt, lbit_pos;
4188 Sym *s, *ss, **ps;
4189 AttributeDef ad;
4191 a = tok; /* save decl type */
4192 next();
4193 if (tok != '{') {
4194 v = tok;
4195 next();
4196 /* struct already defined ? return it */
4197 /* XXX: check consistency */
4198 s = sym_find(v | SYM_STRUCT);
4199 if (s) {
4200 if (s->t != a)
4201 error("invalid type");
4202 goto do_decl;
4204 } else {
4205 v = anon_sym++;
4207 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4208 /* put struct/union/enum name in type */
4209 do_decl:
4210 u = u | (v << VT_STRUCT_SHIFT);
4212 if (tok == '{') {
4213 next();
4214 if (s->c)
4215 error("struct/union/enum already defined");
4216 /* cannot be empty */
4217 c = 0;
4218 maxalign = 0;
4219 ps = &s->next;
4220 bit_pos = 0;
4221 offset = 0;
4222 while (1) {
4223 if (a == TOK_ENUM) {
4224 v = tok;
4225 next();
4226 if (tok == '=') {
4227 next();
4228 c = expr_const();
4230 /* enum symbols have static storage */
4231 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4232 if (tok == ',')
4233 next();
4234 c++;
4235 } else {
4236 parse_btype(&b, &ad);
4237 while (1) {
4238 bit_size = -1;
4239 v = 0;
4240 if (tok != ':') {
4241 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4242 if ((t & VT_BTYPE) == VT_FUNC ||
4243 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4244 error("invalid type for '%s'",
4245 get_tok_str(v, NULL));
4246 } else {
4247 t = b;
4249 if (tok == ':') {
4250 next();
4251 bit_size = expr_const();
4252 /* XXX: handle v = 0 case for messages */
4253 if (bit_size < 0)
4254 error("negative width in bit-field '%s'",
4255 get_tok_str(v, NULL));
4256 if (v && bit_size == 0)
4257 error("zero width for bit-field '%s'",
4258 get_tok_str(v, NULL));
4260 size = type_size(t, &align);
4261 lbit_pos = 0;
4262 if (bit_size >= 0) {
4263 bt = t & VT_BTYPE;
4264 if (bt != VT_INT &&
4265 bt != VT_BYTE &&
4266 bt != VT_SHORT)
4267 error("bitfields must have scalar type");
4268 bsize = size * 8;
4269 if (bit_size > bsize) {
4270 error("width of '%s' exceeds its type",
4271 get_tok_str(v, NULL));
4272 } else if (bit_size == bsize) {
4273 /* no need for bit fields */
4274 bit_pos = 0;
4275 } else if (bit_size == 0) {
4276 /* XXX: what to do if only padding in a
4277 structure ? */
4278 /* zero size: means to pad */
4279 if (bit_pos > 0)
4280 bit_pos = bsize;
4281 } else {
4282 /* we do not have enough room ? */
4283 if ((bit_pos + bit_size) > bsize)
4284 bit_pos = 0;
4285 lbit_pos = bit_pos;
4286 /* XXX: handle LSB first */
4287 t |= VT_BITFIELD |
4288 (bit_pos << VT_STRUCT_SHIFT) |
4289 (bit_size << (VT_STRUCT_SHIFT + 6));
4290 bit_pos += bit_size;
4292 } else {
4293 bit_pos = 0;
4295 if (v) {
4296 /* add new memory data only if starting
4297 bit field */
4298 if (lbit_pos == 0) {
4299 if (a == TOK_STRUCT) {
4300 c = (c + align - 1) & -align;
4301 offset = c;
4302 c += size;
4303 } else {
4304 offset = 0;
4305 if (size > c)
4306 c = size;
4308 if (align > maxalign)
4309 maxalign = align;
4311 #if 0
4312 printf("add field %s offset=%d",
4313 get_tok_str(v, NULL), offset);
4314 if (t & VT_BITFIELD) {
4315 printf(" pos=%d size=%d",
4316 (t >> VT_STRUCT_SHIFT) & 0x3f,
4317 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4319 printf("\n");
4320 #endif
4321 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4322 *ps = ss;
4323 ps = &ss->next;
4325 if (tok == ';' || tok == -1)
4326 break;
4327 skip(',');
4329 skip(';');
4331 if (tok == '}')
4332 break;
4334 skip('}');
4335 /* size for struct/union, dummy for enum */
4336 s->c = (c + maxalign - 1) & -maxalign;
4338 return u;
4341 /* return 0 if no type declaration. otherwise, return the basic type
4342 and skip it.
4344 int parse_btype(int *type_ptr, AttributeDef *ad)
4346 int t, u, type_found;
4347 Sym *s;
4349 memset(ad, 0, sizeof(AttributeDef));
4350 type_found = 0;
4351 t = 0;
4352 while(1) {
4353 switch(tok) {
4354 /* basic types */
4355 case TOK_CHAR:
4356 u = VT_BYTE;
4357 basic_type:
4358 next();
4359 basic_type1:
4360 if ((t & VT_BTYPE) != 0)
4361 error("too many basic types");
4362 t |= u;
4363 break;
4364 case TOK_VOID:
4365 u = VT_VOID;
4366 goto basic_type;
4367 case TOK_SHORT:
4368 u = VT_SHORT;
4369 goto basic_type;
4370 case TOK_INT:
4371 next();
4372 break;
4373 case TOK_LONG:
4374 next();
4375 if ((t & VT_BTYPE) == VT_DOUBLE) {
4376 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4377 } else if ((t & VT_BTYPE) == VT_LONG) {
4378 t = (t & ~VT_BTYPE) | VT_LLONG;
4379 } else {
4380 u = VT_LONG;
4381 goto basic_type1;
4383 break;
4384 case TOK_BOOL:
4385 u = VT_BOOL;
4386 goto basic_type;
4387 case TOK_FLOAT:
4388 u = VT_FLOAT;
4389 goto basic_type;
4390 case TOK_DOUBLE:
4391 next();
4392 if ((t & VT_BTYPE) == VT_LONG) {
4393 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4394 } else {
4395 u = VT_DOUBLE;
4396 goto basic_type1;
4398 break;
4399 case TOK_ENUM:
4400 u = struct_decl(VT_ENUM);
4401 goto basic_type1;
4402 case TOK_STRUCT:
4403 case TOK_UNION:
4404 u = struct_decl(VT_STRUCT);
4405 goto basic_type1;
4407 /* type modifiers */
4408 case TOK_CONST:
4409 case TOK_VOLATILE:
4410 case TOK_REGISTER:
4411 case TOK_SIGNED:
4412 case TOK___SIGNED__:
4413 case TOK_AUTO:
4414 case TOK_INLINE:
4415 case TOK___INLINE__:
4416 case TOK_RESTRICT:
4417 next();
4418 break;
4419 case TOK_UNSIGNED:
4420 t |= VT_UNSIGNED;
4421 next();
4422 break;
4424 /* storage */
4425 case TOK_EXTERN:
4426 t |= VT_EXTERN;
4427 next();
4428 break;
4429 case TOK_STATIC:
4430 t |= VT_STATIC;
4431 next();
4432 break;
4433 case TOK_TYPEDEF:
4434 t |= VT_TYPEDEF;
4435 next();
4436 break;
4437 /* GNUC attribute */
4438 case TOK___ATTRIBUTE__:
4439 parse_attribute(ad);
4440 break;
4441 default:
4442 s = sym_find(tok);
4443 if (!s || !(s->t & VT_TYPEDEF))
4444 goto the_end;
4445 t |= (s->t & ~VT_TYPEDEF);
4446 next();
4447 break;
4449 type_found = 1;
4451 the_end:
4452 /* long is never used as type */
4453 if ((t & VT_BTYPE) == VT_LONG)
4454 t = (t & ~VT_BTYPE) | VT_INT;
4455 *type_ptr = t;
4456 return type_found;
4459 int post_type(int t, AttributeDef *ad)
4461 int p, n, pt, l, t1;
4462 Sym **plast, *s, *first;
4463 AttributeDef ad1;
4465 if (tok == '(') {
4466 /* function declaration */
4467 next();
4468 l = 0;
4469 first = NULL;
4470 plast = &first;
4471 while (tok != ')') {
4472 /* read param name and compute offset */
4473 if (l != FUNC_OLD) {
4474 if (!parse_btype(&pt, &ad1)) {
4475 if (l) {
4476 error("invalid type");
4477 } else {
4478 l = FUNC_OLD;
4479 goto old_proto;
4482 l = FUNC_NEW;
4483 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4484 break;
4485 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4486 if ((pt & VT_BTYPE) == VT_VOID)
4487 error("parameter declared as void");
4488 } else {
4489 old_proto:
4490 n = tok;
4491 pt = VT_INT;
4492 next();
4494 /* array must be transformed to pointer according to ANSI C */
4495 pt &= ~VT_ARRAY;
4496 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4497 *plast = s;
4498 plast = &s->next;
4499 if (tok == ',') {
4500 next();
4501 if (l == FUNC_NEW && tok == TOK_DOTS) {
4502 l = FUNC_ELLIPSIS;
4503 next();
4504 break;
4508 /* if no parameters, then old type prototype */
4509 if (l == 0)
4510 l = FUNC_OLD;
4511 skip(')');
4512 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4513 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4514 /* we push a anonymous symbol which will contain the function prototype */
4515 p = anon_sym++;
4516 s = sym_push(p, t, ad->func_call, l);
4517 s->next = first;
4518 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4519 } else if (tok == '[') {
4520 /* array definition */
4521 next();
4522 n = -1;
4523 if (tok != ']') {
4524 n = expr_const();
4525 if (n < 0)
4526 error("invalid array size");
4528 skip(']');
4529 /* parse next post type */
4530 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4531 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4533 /* we push a anonymous symbol which will contain the array
4534 element type */
4535 p = anon_sym++;
4536 sym_push(p, t, 0, n);
4537 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4539 return t;
4542 /* Read a type declaration (except basic type), and return the
4543 type. 'td' is a bitmask indicating which kind of type decl is
4544 expected. 't' should contain the basic type. 'ad' is the attribute
4545 definition of the basic type. It can be modified by type_decl(). */
4546 int type_decl(AttributeDef *ad, int *v, int t, int td)
4548 int u, p;
4549 Sym *s;
4551 while (tok == '*') {
4552 next();
4553 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4554 next();
4555 t = mk_pointer(t);
4558 /* recursive type */
4559 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4560 if (tok == '(') {
4561 next();
4562 /* XXX: this is not correct to modify 'ad' at this point, but
4563 the syntax is not clear */
4564 if (tok == TOK___ATTRIBUTE__)
4565 parse_attribute(ad);
4566 u = type_decl(ad, v, 0, td);
4567 skip(')');
4568 } else {
4569 u = 0;
4570 /* type identifier */
4571 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4572 *v = tok;
4573 next();
4574 } else {
4575 if (!(td & TYPE_ABSTRACT))
4576 expect("identifier");
4577 *v = 0;
4580 /* append t at the end of u */
4581 t = post_type(t, ad);
4582 if (tok == TOK___ATTRIBUTE__)
4583 parse_attribute(ad);
4584 if (!u)
4585 return t;
4586 p = u;
4587 while(1) {
4588 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4589 p = s->t;
4590 if (!p) {
4591 s->t = t;
4592 break;
4595 return u;
4598 /* define a new external reference to a symbol 'v' of type 'u' */
4599 Sym *external_sym(int v, int u, int r)
4601 Sym *s;
4603 s = sym_find(v);
4604 if (!s) {
4605 /* push forward reference */
4606 s = sym_push1(&global_stack,
4607 v, u | VT_EXTERN, 0);
4608 s->r = r | VT_CONST | VT_SYM;
4610 return s;
4613 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4614 static int lvalue_type(int t)
4616 int bt, r;
4617 r = VT_LVAL;
4618 bt = t & VT_BTYPE;
4619 if (bt == VT_BYTE)
4620 r |= VT_LVAL_BYTE;
4621 else if (bt == VT_SHORT)
4622 r |= VT_LVAL_SHORT;
4623 else
4624 return r;
4625 if (t & VT_UNSIGNED)
4626 r |= VT_LVAL_UNSIGNED;
4627 return r;
4630 /* indirection with full error checking and bound check */
4631 static void indir(void)
4633 if ((vtop->t & VT_BTYPE) != VT_PTR)
4634 expect("pointer");
4635 if (vtop->r & VT_LVAL)
4636 gv(RC_INT);
4637 vtop->t = pointed_type(vtop->t);
4638 /* an array is never an lvalue */
4639 if (!(vtop->t & VT_ARRAY)) {
4640 vtop->r |= lvalue_type(vtop->t);
4641 /* if bound checking, the referenced pointer must be checked */
4642 if (do_bounds_check)
4643 vtop->r |= VT_MUSTBOUND;
4647 /* pass a parameter to a function and do type checking and casting */
4648 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
4650 int func_type;
4651 func_type = func->c;
4652 if (func_type == FUNC_OLD ||
4653 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
4654 /* default casting : only need to convert float to double */
4655 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
4656 gen_cast(VT_DOUBLE);
4657 } else if (arg == NULL) {
4658 error("too many arguments to function");
4659 } else {
4660 gen_assign_cast(arg->t);
4662 gfunc_param(gf);
4665 void unary(void)
4667 int n, t, ft, fc, align, size, r, data_offset;
4668 Sym *s;
4669 GFuncContext gf;
4670 AttributeDef ad;
4672 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
4673 vpushi(tokc.i);
4674 next();
4675 } else if (tok == TOK_CUINT) {
4676 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
4677 next();
4678 } else if (tok == TOK_CLLONG) {
4679 vsetc(VT_LLONG, VT_CONST, &tokc);
4680 next();
4681 } else if (tok == TOK_CULLONG) {
4682 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
4683 next();
4684 } else if (tok == TOK_CFLOAT) {
4685 vsetc(VT_FLOAT, VT_CONST, &tokc);
4686 next();
4687 } else if (tok == TOK_CDOUBLE) {
4688 vsetc(VT_DOUBLE, VT_CONST, &tokc);
4689 next();
4690 } else if (tok == TOK_CLDOUBLE) {
4691 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
4692 next();
4693 } else if (tok == TOK___FUNC__) {
4694 void *ptr;
4695 int len;
4696 /* special function name identifier */
4698 len = strlen(funcname) + 1;
4699 /* generate char[len] type */
4700 t = VT_ARRAY | mk_pointer(VT_BYTE);
4701 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4702 s->c = len;
4703 vpush_ref(t, data_section, data_section->data_offset, len);
4704 ptr = section_ptr_add(data_section, len);
4705 memcpy(ptr, funcname, len);
4706 next();
4707 } else if (tok == TOK_LSTR) {
4708 t = VT_INT;
4709 goto str_init;
4710 } else if (tok == TOK_STR) {
4711 /* string parsing */
4712 t = VT_BYTE;
4713 str_init:
4714 type_size(t, &align);
4715 data_offset = data_section->data_offset;
4716 data_offset = (data_offset + align - 1) & -align;
4717 fc = data_offset;
4718 /* we must declare it as an array first to use initializer parser */
4719 t = VT_ARRAY | mk_pointer(t);
4720 decl_initializer(t, data_section, data_offset, 1, 0);
4721 size = type_size(t, &align);
4722 data_offset += size;
4723 vpush_ref(t, data_section, fc, size);
4724 data_section->data_offset = data_offset;
4725 } else {
4726 t = tok;
4727 next();
4728 if (t == '(') {
4729 /* cast ? */
4730 if (parse_btype(&t, &ad)) {
4731 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4732 skip(')');
4733 /* check ISOC99 compound literal */
4734 if (tok == '{') {
4735 /* data is allocated locally by default */
4736 if (global_expr)
4737 r = VT_CONST;
4738 else
4739 r = VT_LOCAL;
4740 /* all except arrays are lvalues */
4741 if (!(ft & VT_ARRAY))
4742 r |= lvalue_type(ft);
4743 memset(&ad, 0, sizeof(AttributeDef));
4744 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
4745 } else {
4746 unary();
4747 gen_cast(ft);
4749 } else {
4750 gexpr();
4751 skip(')');
4753 } else if (t == '*') {
4754 unary();
4755 indir();
4756 } else if (t == '&') {
4757 unary();
4758 /* functions names must be treated as function pointers,
4759 except for unary '&' and sizeof. Since we consider that
4760 functions are not lvalues, we only have to handle it
4761 there and in function calls. */
4762 /* arrays can also be used although they are not lvalues */
4763 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
4764 !(vtop->t & VT_ARRAY))
4765 test_lvalue();
4766 vtop->t = mk_pointer(vtop->t);
4767 gaddrof();
4768 } else
4769 if (t == '!') {
4770 unary();
4771 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
4772 vtop->c.i = !vtop->c.i;
4773 else if ((vtop->r & VT_VALMASK) == VT_CMP)
4774 vtop->c.i = vtop->c.i ^ 1;
4775 else
4776 vset(VT_INT, VT_JMP, gtst(1, 0));
4777 } else
4778 if (t == '~') {
4779 unary();
4780 vpushi(-1);
4781 gen_op('^');
4782 } else
4783 if (t == '+') {
4784 /* in order to force cast, we add zero */
4785 unary();
4786 if ((vtop->t & VT_BTYPE) == VT_PTR)
4787 error("pointer not accepted for unary plus");
4788 vpushi(0);
4789 gen_op('+');
4790 } else
4791 if (t == TOK_SIZEOF) {
4792 if (tok == '(') {
4793 next();
4794 if (parse_btype(&t, &ad)) {
4795 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
4796 } else {
4797 /* XXX: some code could be generated: add eval
4798 flag */
4799 gexpr();
4800 t = vtop->t;
4801 vpop();
4803 skip(')');
4804 } else {
4805 unary();
4806 t = vtop->t;
4807 vpop();
4809 vpushi(type_size(t, &t));
4810 } else
4811 if (t == TOK_INC || t == TOK_DEC) {
4812 unary();
4813 inc(0, t);
4814 } else if (t == '-') {
4815 vpushi(0);
4816 unary();
4817 gen_op('-');
4818 } else
4820 if (t < TOK_UIDENT)
4821 expect("identifier");
4822 s = sym_find(t);
4823 if (!s) {
4824 if (tok != '(')
4825 error("'%s' undeclared", get_tok_str(t, NULL));
4826 /* for simple function calls, we tolerate undeclared
4827 external reference to int() function */
4828 s = external_sym(t, func_old_type, 0);
4830 vset(s->t, s->r, s->c);
4831 /* if forward reference, we must point to s */
4832 if (vtop->r & VT_SYM)
4833 vtop->c.sym = s;
4837 /* post operations */
4838 while (1) {
4839 if (tok == TOK_INC || tok == TOK_DEC) {
4840 inc(1, tok);
4841 next();
4842 } else if (tok == '.' || tok == TOK_ARROW) {
4843 /* field */
4844 if (tok == TOK_ARROW)
4845 indir();
4846 test_lvalue();
4847 gaddrof();
4848 next();
4849 /* expect pointer on structure */
4850 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
4851 expect("struct or union");
4852 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4853 /* find field */
4854 tok |= SYM_FIELD;
4855 while ((s = s->next) != NULL) {
4856 if (s->v == tok)
4857 break;
4859 if (!s)
4860 error("field not found");
4861 /* add field offset to pointer */
4862 vtop->t = char_pointer_type; /* change type to 'char *' */
4863 vpushi(s->c);
4864 gen_op('+');
4865 /* change type to field type, and set to lvalue */
4866 vtop->t = s->t;
4867 /* an array is never an lvalue */
4868 if (!(vtop->t & VT_ARRAY))
4869 vtop->r |= lvalue_type(vtop->t);
4870 next();
4871 } else if (tok == '[') {
4872 next();
4873 gexpr();
4874 gen_op('+');
4875 indir();
4876 skip(']');
4877 } else if (tok == '(') {
4878 SValue ret;
4879 Sym *sa;
4881 /* function call */
4882 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
4883 /* pointer test (no array accepted) */
4884 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4885 vtop->t = pointed_type(vtop->t);
4886 if ((vtop->t & VT_BTYPE) != VT_FUNC)
4887 goto error_func;
4888 } else {
4889 error_func:
4890 expect("function pointer");
4892 } else {
4893 vtop->r &= ~VT_LVAL; /* no lvalue */
4895 /* get return type */
4896 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
4897 save_regs(0); /* save used temporary registers */
4898 gfunc_start(&gf, s->r);
4899 next();
4900 sa = s->next; /* first parameter */
4901 #ifdef INVERT_FUNC_PARAMS
4903 int parlevel;
4904 Sym *args, *s1;
4905 ParseState saved_parse_state;
4906 TokenString str;
4908 /* read each argument and store it on a stack */
4909 /* XXX: merge it with macro args ? */
4910 args = NULL;
4911 if (tok != ')') {
4912 for(;;) {
4913 tok_str_new(&str);
4914 parlevel = 0;
4915 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
4916 tok != -1) {
4917 if (tok == '(')
4918 parlevel++;
4919 else if (tok == ')')
4920 parlevel--;
4921 tok_str_add_tok(&str);
4922 next();
4924 tok_str_add(&str, -1); /* end of file added */
4925 tok_str_add(&str, 0);
4926 s1 = sym_push2(&args, 0, 0, (int)str.str);
4927 s1->next = sa; /* add reference to argument */
4928 if (sa)
4929 sa = sa->next;
4930 if (tok == ')')
4931 break;
4932 skip(',');
4936 /* now generate code in reverse order by reading the stack */
4937 save_parse_state(&saved_parse_state);
4938 while (args) {
4939 macro_ptr = (int *)args->c;
4940 next();
4941 expr_eq();
4942 if (tok != -1)
4943 expect("',' or ')'");
4944 gfunc_param_typed(&gf, s, args->next);
4945 s1 = args->prev;
4946 free((int *)args->c);
4947 free(args);
4948 args = s1;
4950 restore_parse_state(&saved_parse_state);
4952 #endif
4953 /* compute first implicit argument if a structure is returned */
4954 if ((s->t & VT_BTYPE) == VT_STRUCT) {
4955 /* get some space for the returned structure */
4956 size = type_size(s->t, &align);
4957 loc = (loc - size) & -align;
4958 ret.t = s->t;
4959 ret.r = VT_LOCAL | VT_LVAL;
4960 /* pass it as 'int' to avoid structure arg passing
4961 problems */
4962 vset(VT_INT, VT_LOCAL, loc);
4963 ret.c = vtop->c;
4964 gfunc_param(&gf);
4965 } else {
4966 ret.t = s->t;
4967 ret.r2 = VT_CONST;
4968 /* return in register */
4969 if (is_float(ret.t)) {
4970 ret.r = REG_FRET;
4971 } else {
4972 if ((ret.t & VT_BTYPE) == VT_LLONG)
4973 ret.r2 = REG_LRET;
4974 ret.r = REG_IRET;
4976 ret.c.i = 0;
4978 #ifndef INVERT_FUNC_PARAMS
4979 if (tok != ')') {
4980 for(;;) {
4981 expr_eq();
4982 gfunc_param_typed(&gf, s, sa);
4983 if (sa)
4984 sa = sa->next;
4985 if (tok == ')')
4986 break;
4987 skip(',');
4990 #endif
4991 if (sa)
4992 error("too few arguments to function");
4993 skip(')');
4994 gfunc_call(&gf);
4995 /* return value */
4996 vsetc(ret.t, ret.r, &ret.c);
4997 vtop->r2 = ret.r2;
4998 } else {
4999 break;
5004 void uneq(void)
5006 int t;
5008 unary();
5009 if (tok == '=' ||
5010 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5011 tok == TOK_A_XOR || tok == TOK_A_OR ||
5012 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5013 test_lvalue();
5014 t = tok;
5015 next();
5016 if (t == '=') {
5017 expr_eq();
5018 } else {
5019 vdup();
5020 expr_eq();
5021 gen_op(t & 0x7f);
5023 vstore();
5027 void sum(int l)
5029 int t;
5031 if (l == 0)
5032 uneq();
5033 else {
5034 sum(--l);
5035 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5036 (l == 1 && (tok == '+' || tok == '-')) ||
5037 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5038 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5039 tok == TOK_ULT || tok == TOK_UGE)) ||
5040 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5041 (l == 5 && tok == '&') ||
5042 (l == 6 && tok == '^') ||
5043 (l == 7 && tok == '|') ||
5044 (l == 8 && tok == TOK_LAND) ||
5045 (l == 9 && tok == TOK_LOR)) {
5046 t = tok;
5047 next();
5048 sum(l);
5049 gen_op(t);
5054 /* only used if non constant */
5055 void eand(void)
5057 int t;
5059 sum(8);
5060 t = 0;
5061 while (1) {
5062 if (tok != TOK_LAND) {
5063 if (t) {
5064 t = gtst(1, t);
5065 vset(VT_INT, VT_JMPI, t);
5067 break;
5069 t = gtst(1, t);
5070 next();
5071 sum(8);
5075 void eor(void)
5077 int t;
5079 eand();
5080 t = 0;
5081 while (1) {
5082 if (tok != TOK_LOR) {
5083 if (t) {
5084 t = gtst(0, t);
5085 vset(VT_INT, VT_JMP, t);
5087 break;
5089 t = gtst(0, t);
5090 next();
5091 eand();
5095 /* XXX: better constant handling */
5096 void expr_eq(void)
5098 int t, u, c, r1, r2, rc;
5100 if (const_wanted) {
5101 sum(10);
5102 if (tok == '?') {
5103 c = vtop->c.i;
5104 vpop();
5105 next();
5106 gexpr();
5107 t = vtop->c.i;
5108 vpop();
5109 skip(':');
5110 expr_eq();
5111 if (c)
5112 vtop->c.i = t;
5114 } else {
5115 eor();
5116 if (tok == '?') {
5117 next();
5118 save_regs(1); /* we need to save all registers here except
5119 at the top because it is a branch point */
5120 t = gtst(1, 0);
5121 gexpr();
5122 /* XXX: long long handling ? */
5123 rc = RC_INT;
5124 if (is_float(vtop->t))
5125 rc = RC_FLOAT;
5126 r1 = gv(rc);
5127 vtop--; /* no vpop so that FP stack is not flushed */
5128 skip(':');
5129 u = gjmp(0);
5131 gsym(t);
5132 expr_eq();
5133 r2 = gv(rc);
5134 move_reg(r1, r2);
5135 vtop->r = r1;
5136 gsym(u);
5141 void gexpr(void)
5143 while (1) {
5144 expr_eq();
5145 if (tok != ',')
5146 break;
5147 vpop();
5148 next();
5152 /* parse a constant expression and return value in vtop */
5153 void expr_const1(void)
5155 int a;
5156 a = const_wanted;
5157 const_wanted = 1;
5158 expr_eq();
5159 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5160 expect("constant");
5161 const_wanted = a;
5164 /* parse an integer constant and return its value */
5165 int expr_const(void)
5167 int c;
5168 expr_const1();
5169 c = vtop->c.i;
5170 vpop();
5171 return c;
5174 /* return the label token if current token is a label, otherwise
5175 return zero */
5176 int is_label(void)
5178 int t;
5179 CValue c;
5181 /* fast test first */
5182 if (tok < TOK_UIDENT)
5183 return 0;
5184 /* no need to save tokc since we expect an identifier */
5185 t = tok;
5186 c = tokc;
5187 next();
5188 if (tok == ':') {
5189 next();
5190 return t;
5191 } else {
5192 /* XXX: may not work in all cases (macros ?) */
5193 tok1 = tok;
5194 tok1c = tokc;
5195 tok = t;
5196 tokc = c;
5197 return 0;
5201 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5203 int a, b, c, d;
5204 Sym *s;
5206 /* generate line number info */
5207 if (do_debug &&
5208 (last_line_num != file->line_num || last_ind != ind)) {
5209 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5210 last_ind = ind;
5211 last_line_num = file->line_num;
5214 if (tok == TOK_IF) {
5215 /* if test */
5216 next();
5217 skip('(');
5218 gexpr();
5219 skip(')');
5220 a = gtst(1, 0);
5221 block(bsym, csym, case_sym, def_sym, case_reg);
5222 c = tok;
5223 if (c == TOK_ELSE) {
5224 next();
5225 d = gjmp(0);
5226 gsym(a);
5227 block(bsym, csym, case_sym, def_sym, case_reg);
5228 gsym(d); /* patch else jmp */
5229 } else
5230 gsym(a);
5231 } else if (tok == TOK_WHILE) {
5232 next();
5233 d = ind;
5234 skip('(');
5235 gexpr();
5236 skip(')');
5237 a = gtst(1, 0);
5238 b = 0;
5239 block(&a, &b, case_sym, def_sym, case_reg);
5240 gjmp_addr(d);
5241 gsym(a);
5242 gsym_addr(b, d);
5243 } else if (tok == '{') {
5244 next();
5245 /* declarations */
5246 s = local_stack.top;
5247 while (tok != '}') {
5248 decl(VT_LOCAL);
5249 if (tok != '}')
5250 block(bsym, csym, case_sym, def_sym, case_reg);
5252 /* pop locally defined symbols */
5253 sym_pop(&local_stack, s);
5254 next();
5255 } else if (tok == TOK_RETURN) {
5256 next();
5257 if (tok != ';') {
5258 gexpr();
5259 gen_assign_cast(func_vt);
5260 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5261 /* if returning structure, must copy it to implicit
5262 first pointer arg location */
5263 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5264 indir();
5265 vswap();
5266 /* copy structure value to pointer */
5267 vstore();
5268 } else if (is_float(func_vt)) {
5269 gv(RC_FRET);
5270 } else {
5271 gv(RC_IRET);
5273 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5275 skip(';');
5276 rsym = gjmp(rsym); /* jmp */
5277 } else if (tok == TOK_BREAK) {
5278 /* compute jump */
5279 if (!bsym)
5280 error("cannot break");
5281 *bsym = gjmp(*bsym);
5282 next();
5283 skip(';');
5284 } else if (tok == TOK_CONTINUE) {
5285 /* compute jump */
5286 if (!csym)
5287 error("cannot continue");
5288 *csym = gjmp(*csym);
5289 next();
5290 skip(';');
5291 } else if (tok == TOK_FOR) {
5292 int e;
5293 next();
5294 skip('(');
5295 if (tok != ';') {
5296 gexpr();
5297 vpop();
5299 skip(';');
5300 d = ind;
5301 c = ind;
5302 a = 0;
5303 b = 0;
5304 if (tok != ';') {
5305 gexpr();
5306 a = gtst(1, 0);
5308 skip(';');
5309 if (tok != ')') {
5310 e = gjmp(0);
5311 c = ind;
5312 gexpr();
5313 vpop();
5314 gjmp_addr(d);
5315 gsym(e);
5317 skip(')');
5318 block(&a, &b, case_sym, def_sym, case_reg);
5319 gjmp_addr(c);
5320 gsym(a);
5321 gsym_addr(b, c);
5322 } else
5323 if (tok == TOK_DO) {
5324 next();
5325 a = 0;
5326 b = 0;
5327 d = ind;
5328 block(&a, &b, case_sym, def_sym, case_reg);
5329 skip(TOK_WHILE);
5330 skip('(');
5331 gsym(b);
5332 gexpr();
5333 c = gtst(0, 0);
5334 gsym_addr(c, d);
5335 skip(')');
5336 gsym(a);
5337 skip(';');
5338 } else
5339 if (tok == TOK_SWITCH) {
5340 next();
5341 skip('(');
5342 gexpr();
5343 /* XXX: other types than integer */
5344 case_reg = gv(RC_INT);
5345 vpop();
5346 skip(')');
5347 a = 0;
5348 b = gjmp(0); /* jump to first case */
5349 c = 0;
5350 block(&a, csym, &b, &c, case_reg);
5351 /* if no default, jmp after switch */
5352 if (c == 0)
5353 c = ind;
5354 /* default label */
5355 gsym_addr(b, c);
5356 /* break label */
5357 gsym(a);
5358 } else
5359 if (tok == TOK_CASE) {
5360 int v1, v2;
5361 if (!case_sym)
5362 expect("switch");
5363 next();
5364 v1 = expr_const();
5365 v2 = v1;
5366 if (gnu_ext && tok == TOK_DOTS) {
5367 next();
5368 v2 = expr_const();
5369 if (v2 < v1)
5370 warning("empty case range");
5372 /* since a case is like a label, we must skip it with a jmp */
5373 b = gjmp(0);
5374 gsym(*case_sym);
5375 vset(VT_INT, case_reg, 0);
5376 vpushi(v1);
5377 if (v1 == v2) {
5378 gen_op(TOK_EQ);
5379 *case_sym = gtst(1, 0);
5380 } else {
5381 gen_op(TOK_GE);
5382 *case_sym = gtst(1, 0);
5383 vset(VT_INT, case_reg, 0);
5384 vpushi(v2);
5385 gen_op(TOK_LE);
5386 *case_sym = gtst(1, *case_sym);
5388 gsym(b);
5389 skip(':');
5390 block(bsym, csym, case_sym, def_sym, case_reg);
5391 } else
5392 if (tok == TOK_DEFAULT) {
5393 next();
5394 skip(':');
5395 if (!def_sym)
5396 expect("switch");
5397 if (*def_sym)
5398 error("too many 'default'");
5399 *def_sym = ind;
5400 block(bsym, csym, case_sym, def_sym, case_reg);
5401 } else
5402 if (tok == TOK_GOTO) {
5403 next();
5404 s = sym_find1(&label_stack, tok);
5405 /* put forward definition if needed */
5406 if (!s)
5407 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5408 /* label already defined */
5409 if (s->t & LABEL_FORWARD)
5410 s->c = gjmp(s->c);
5411 else
5412 gjmp_addr(s->c);
5413 next();
5414 skip(';');
5415 } else {
5416 b = is_label();
5417 if (b) {
5418 /* label case */
5419 s = sym_find1(&label_stack, b);
5420 if (s) {
5421 if (!(s->t & LABEL_FORWARD))
5422 error("multiple defined label");
5423 gsym(s->c);
5424 s->c = ind;
5425 s->t = 0;
5426 } else {
5427 sym_push1(&label_stack, b, 0, ind);
5429 /* we accept this, but it is a mistake */
5430 if (tok == '}')
5431 warning("deprecated use of label at end of compound statement");
5432 else
5433 block(bsym, csym, case_sym, def_sym, case_reg);
5434 } else {
5435 /* expression case */
5436 if (tok != ';') {
5437 gexpr();
5438 vpop();
5440 skip(';');
5445 /* t is the array or struct type. c is the array or struct
5446 address. cur_index/cur_field is the pointer to the current
5447 value. 'size_only' is true if only size info is needed (only used
5448 in arrays) */
5449 void decl_designator(int t, Section *sec, unsigned long c,
5450 int *cur_index, Sym **cur_field,
5451 int size_only)
5453 Sym *s, *f;
5454 int notfirst, index, align, l;
5456 notfirst = 0;
5457 if (gnu_ext && (l = is_label()) != 0)
5458 goto struct_field;
5460 while (tok == '[' || tok == '.') {
5461 if (tok == '[') {
5462 if (!(t & VT_ARRAY))
5463 expect("array type");
5464 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5465 next();
5466 index = expr_const();
5467 if (index < 0 || (s->c >= 0 && index >= s->c))
5468 expect("invalid index");
5469 skip(']');
5470 if (!notfirst)
5471 *cur_index = index;
5472 t = pointed_type(t);
5473 c += index * type_size(t, &align);
5474 } else {
5475 next();
5476 l = tok;
5477 next();
5478 struct_field:
5479 if ((t & VT_BTYPE) != VT_STRUCT)
5480 expect("struct/union type");
5481 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5482 l |= SYM_FIELD;
5483 f = s->next;
5484 while (f) {
5485 if (f->v == l)
5486 break;
5487 f = f->next;
5489 if (!f)
5490 expect("field");
5491 if (!notfirst)
5492 *cur_field = f;
5493 t = f->t | (t & ~VT_TYPE);
5494 c += f->c;
5496 notfirst = 1;
5498 if (notfirst) {
5499 if (tok == '=') {
5500 next();
5501 } else {
5502 if (!gnu_ext)
5503 expect("=");
5505 } else {
5506 if (t & VT_ARRAY) {
5507 index = *cur_index;
5508 t = pointed_type(t);
5509 c += index * type_size(t, &align);
5510 } else {
5511 f = *cur_field;
5512 if (!f)
5513 error("too many field init");
5514 t = f->t | (t & ~VT_TYPE);
5515 c += f->c;
5518 decl_initializer(t, sec, c, 0, size_only);
5521 #define EXPR_VAL 0
5522 #define EXPR_CONST 1
5523 #define EXPR_ANY 2
5525 /* store a value or an expression directly in global data or in local array */
5526 void init_putv(int t, Section *sec, unsigned long c,
5527 int v, int expr_type)
5529 int saved_global_expr, bt;
5530 void *ptr;
5532 switch(expr_type) {
5533 case EXPR_VAL:
5534 vpushi(v);
5535 break;
5536 case EXPR_CONST:
5537 /* compound literals must be allocated globally in this case */
5538 saved_global_expr = global_expr;
5539 global_expr = 1;
5540 expr_const1();
5541 global_expr = saved_global_expr;
5542 break;
5543 case EXPR_ANY:
5544 expr_eq();
5545 break;
5548 if (sec) {
5549 /* XXX: not portable */
5550 /* XXX: generate error if incorrect relocation */
5551 gen_assign_cast(t);
5552 bt = t & VT_BTYPE;
5553 ptr = sec->data + c;
5554 if ((vtop->r & VT_SYM) &&
5555 (bt == VT_BYTE ||
5556 bt == VT_SHORT ||
5557 bt == VT_DOUBLE ||
5558 bt == VT_LDOUBLE ||
5559 bt == VT_LLONG))
5560 error("initializer element is not computable at load time");
5561 switch(bt) {
5562 case VT_BYTE:
5563 *(char *)ptr = vtop->c.i;
5564 break;
5565 case VT_SHORT:
5566 *(short *)ptr = vtop->c.i;
5567 break;
5568 case VT_DOUBLE:
5569 *(double *)ptr = vtop->c.d;
5570 break;
5571 case VT_LDOUBLE:
5572 *(long double *)ptr = vtop->c.ld;
5573 break;
5574 case VT_LLONG:
5575 *(long long *)ptr = vtop->c.ll;
5576 break;
5577 default:
5578 if (vtop->r & VT_SYM) {
5579 greloc(sec, vtop->c.sym, c, R_DATA_32);
5580 *(int *)ptr = 0;
5581 } else {
5582 *(int *)ptr = vtop->c.i;
5584 break;
5586 vtop--;
5587 } else {
5588 vset(t, VT_LOCAL, c);
5589 vswap();
5590 vstore();
5591 vpop();
5595 /* put zeros for variable based init */
5596 void init_putz(int t, Section *sec, unsigned long c, int size)
5598 GFuncContext gf;
5600 if (sec) {
5601 /* nothing to do because globals are already set to zero */
5602 } else {
5603 gfunc_start(&gf, FUNC_CDECL);
5604 vpushi(size);
5605 gfunc_param(&gf);
5606 vpushi(0);
5607 gfunc_param(&gf);
5608 vset(VT_INT, VT_LOCAL, c);
5609 gfunc_param(&gf);
5610 vpush_sym(func_old_type, TOK_memset);
5611 gfunc_call(&gf);
5615 /* 't' contains the type and storage info. 'c' is the offset of the
5616 object in section 'sec'. If 'sec' is NULL, it means stack based
5617 allocation. 'first' is true if array '{' must be read (multi
5618 dimension implicit array init handling). 'size_only' is true if
5619 size only evaluation is wanted (only for arrays). */
5620 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only)
5622 int index, array_length, n, no_oblock, nb, parlevel, i;
5623 int t1, size1, align1, expr_type;
5624 Sym *s, *f;
5625 TokenSym *ts;
5627 if (t & VT_ARRAY) {
5628 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5629 n = s->c;
5630 array_length = 0;
5631 t1 = pointed_type(t);
5632 size1 = type_size(t1, &align1);
5634 no_oblock = 1;
5635 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5636 tok == '{') {
5637 skip('{');
5638 no_oblock = 0;
5641 /* only parse strings here if correct type (otherwise: handle
5642 them as ((w)char *) expressions */
5643 if ((tok == TOK_LSTR &&
5644 (t1 & VT_BTYPE) == VT_INT) ||
5645 (tok == TOK_STR &&
5646 (t1 & VT_BTYPE) == VT_BYTE)) {
5647 /* XXX: move multiple string parsing in parser ? */
5648 while (tok == TOK_STR || tok == TOK_LSTR) {
5649 ts = tokc.ts;
5650 /* compute maximum number of chars wanted */
5651 nb = ts->len;
5652 if (n >= 0 && nb > (n - array_length))
5653 nb = n - array_length;
5654 if (!size_only) {
5655 if (ts->len > nb)
5656 warning("initializer-string for array is too long");
5657 for(i=0;i<nb;i++) {
5658 init_putv(t1, sec, c + (array_length + i) * size1,
5659 ts->str[i], EXPR_VAL);
5662 array_length += nb;
5663 next();
5665 /* only add trailing zero if enough storage (no
5666 warning in this case since it is standard) */
5667 if (n < 0 || array_length < n) {
5668 if (!size_only) {
5669 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5671 array_length++;
5673 } else {
5674 index = 0;
5675 while (tok != '}') {
5676 decl_designator(t, sec, c, &index, NULL, size_only);
5677 if (n >= 0 && index >= n)
5678 error("index too large");
5679 /* must put zero in holes (note that doing it that way
5680 ensures that it even works with designators) */
5681 if (!size_only && array_length < index) {
5682 init_putz(t1, sec, c + array_length * size1,
5683 (index - array_length) * size1);
5685 index++;
5686 if (index > array_length)
5687 array_length = index;
5688 /* special test for multi dimensional arrays (may not
5689 be strictly correct if designators are used at the
5690 same time) */
5691 if (index >= n && no_oblock)
5692 break;
5693 if (tok == '}')
5694 break;
5695 skip(',');
5698 if (!no_oblock)
5699 skip('}');
5700 /* put zeros at the end */
5701 if (!size_only && n >= 0 && array_length < n) {
5702 init_putz(t1, sec, c + array_length * size1,
5703 (n - array_length) * size1);
5705 /* patch type size if needed */
5706 if (n < 0)
5707 s->c = array_length;
5708 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
5709 /* XXX: union needs only one init */
5710 next();
5711 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5712 f = s->next;
5713 array_length = 0;
5714 index = 0;
5715 n = s->c;
5716 while (tok != '}') {
5717 decl_designator(t, sec, c, NULL, &f, size_only);
5718 /* fill with zero between fields */
5719 index = f->c;
5720 if (!size_only && array_length < index) {
5721 init_putz(t, sec, c + array_length,
5722 index - array_length);
5724 index = index + type_size(f->t, &align1);
5725 if (index > array_length)
5726 array_length = index;
5727 if (tok == '}')
5728 break;
5729 skip(',');
5730 f = f->next;
5732 /* put zeros at the end */
5733 if (!size_only && array_length < n) {
5734 init_putz(t, sec, c + array_length,
5735 n - array_length);
5737 skip('}');
5738 } else if (tok == '{') {
5739 next();
5740 decl_initializer(t, sec, c, first, size_only);
5741 skip('}');
5742 } else if (size_only) {
5743 /* just skip expression */
5744 parlevel = 0;
5745 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
5746 tok != -1) {
5747 if (tok == '(')
5748 parlevel++;
5749 else if (tok == ')')
5750 parlevel--;
5751 next();
5753 } else {
5754 /* currently, we always use constant expression for globals
5755 (may change for scripting case) */
5756 expr_type = EXPR_CONST;
5757 if (!sec)
5758 expr_type = EXPR_ANY;
5759 init_putv(t, sec, c, 0, expr_type);
5763 /* parse an initializer for type 't' if 'has_init' is true, and
5764 allocate space in local or global data space ('r' is either
5765 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5766 variable 'v' of scope 'scope' is declared before initializers are
5767 parsed. If 'v' is zero, then a reference to the new object is put
5768 in the value stack. */
5769 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
5770 int v, int scope)
5772 int size, align, addr, data_offset;
5773 int level;
5774 ParseState saved_parse_state;
5775 TokenString init_str;
5776 Section *sec;
5778 size = type_size(t, &align);
5779 /* If unknown size, we must evaluate it before
5780 evaluating initializers because
5781 initializers can generate global data too
5782 (e.g. string pointers or ISOC99 compound
5783 literals). It also simplifies local
5784 initializers handling */
5785 tok_str_new(&init_str);
5786 if (size < 0) {
5787 if (!has_init)
5788 error("unknown type size");
5789 /* get all init string */
5790 level = 0;
5791 while (level > 0 || (tok != ',' && tok != ';')) {
5792 if (tok < 0)
5793 error("unexpected end of file in initializer");
5794 tok_str_add_tok(&init_str);
5795 if (tok == '{')
5796 level++;
5797 else if (tok == '}') {
5798 if (level == 0)
5799 break;
5800 level--;
5802 next();
5804 tok_str_add(&init_str, -1);
5805 tok_str_add(&init_str, 0);
5807 /* compute size */
5808 save_parse_state(&saved_parse_state);
5810 macro_ptr = init_str.str;
5811 next();
5812 decl_initializer(t, NULL, 0, 1, 1);
5813 /* prepare second initializer parsing */
5814 macro_ptr = init_str.str;
5815 next();
5817 /* if still unknown size, error */
5818 size = type_size(t, &align);
5819 if (size < 0)
5820 error("unknown type size");
5822 /* take into account specified alignment if bigger */
5823 if (ad->aligned > align)
5824 align = ad->aligned;
5825 if ((r & VT_VALMASK) == VT_LOCAL) {
5826 sec = NULL;
5827 if (do_bounds_check && (t & VT_ARRAY))
5828 loc--;
5829 #ifdef TCC_TARGET_IL
5830 /* XXX: ugly patch to allocate local variables for IL, just
5831 for testing */
5832 addr = loc;
5833 loc++;
5834 #else
5835 loc = (loc - size) & -align;
5836 addr = loc;
5837 #endif
5838 /* handles bounds */
5839 /* XXX: currently, since we do only one pass, we cannot track
5840 '&' operators, so we add only arrays */
5841 if (do_bounds_check && (t & VT_ARRAY)) {
5842 unsigned long *bounds_ptr;
5843 /* add padding between regions */
5844 loc--;
5845 /* then add local bound info */
5846 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5847 bounds_ptr[0] = addr;
5848 bounds_ptr[1] = size;
5850 } else {
5851 /* compute section */
5852 sec = ad->section;
5853 if (!sec) {
5854 if (has_init)
5855 sec = data_section;
5856 else
5857 sec = bss_section;
5859 data_offset = sec->data_offset;
5860 data_offset = (data_offset + align - 1) & -align;
5861 addr = data_offset;
5862 /* very important to increment global pointer at this time
5863 because initializers themselves can create new initializers */
5864 data_offset += size;
5865 /* add padding if bound check */
5866 if (do_bounds_check)
5867 data_offset++;
5868 sec->data_offset = data_offset;
5870 if (!sec) {
5871 if (v) {
5872 /* local variable */
5873 sym_push(v, t, r, addr);
5874 } else {
5875 /* push local reference */
5876 vset(t, r, addr);
5878 } else {
5879 Sym *sym;
5881 if (v) {
5882 if (scope == VT_CONST) {
5883 /* global scope: see if already defined */
5884 sym = sym_find(v);
5885 if (!sym)
5886 goto do_def;
5887 if (!is_compatible_types(sym->t, t))
5888 error("incompatible types for redefinition of '%s'",
5889 get_tok_str(v, NULL));
5890 if (!(sym->t & VT_EXTERN))
5891 error("redefinition of '%s'", get_tok_str(v, NULL));
5892 sym->t &= ~VT_EXTERN;
5893 } else {
5894 do_def:
5895 sym = sym_push(v, t, r | VT_SYM, 0);
5897 put_extern_sym(sym, sec, addr, size);
5898 } else {
5899 CValue cval;
5901 /* push global reference */
5902 sym = get_sym_ref(t, sec, addr, size);
5903 cval.sym = sym;
5904 vsetc(t, VT_CONST | VT_SYM, &cval);
5907 /* handles bounds now because the symbol must be defined
5908 before for the relocation */
5909 if (do_bounds_check) {
5910 unsigned long *bounds_ptr;
5912 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
5913 /* then add global bound info */
5914 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5915 bounds_ptr[0] = 0; /* relocated */
5916 bounds_ptr[1] = size;
5919 if (has_init) {
5920 decl_initializer(t, sec, addr, 1, 0);
5921 /* restore parse state if needed */
5922 if (init_str.str) {
5923 free(init_str.str);
5924 restore_parse_state(&saved_parse_state);
5929 void put_func_debug(Sym *sym)
5931 char buf[512];
5933 /* stabs info */
5934 /* XXX: we put here a dummy type */
5935 snprintf(buf, sizeof(buf), "%s:%c1",
5936 funcname, sym->t & VT_STATIC ? 'f' : 'F');
5937 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5938 cur_text_section, sym->c);
5939 last_ind = 0;
5940 last_line_num = 0;
5943 /* not finished : try to put some local vars in registers */
5944 //#define CONFIG_REG_VARS
5946 #ifdef CONFIG_REG_VARS
5947 void add_var_ref(int t)
5949 printf("%s:%d: &%s\n",
5950 file->filename, file->line_num,
5951 get_tok_str(t, NULL));
5954 /* first pass on a function with heuristic to extract variable usage
5955 and pointer references to local variables for register allocation */
5956 void analyse_function(void)
5958 int level, t;
5960 for(;;) {
5961 if (tok == -1)
5962 break;
5963 /* any symbol coming after '&' is considered as being a
5964 variable whose reference is taken. It is highly unaccurate
5965 but it is difficult to do better without a complete parse */
5966 if (tok == '&') {
5967 next();
5968 /* if '& number', then no need to examine next tokens */
5969 if (tok == TOK_CINT ||
5970 tok == TOK_CUINT ||
5971 tok == TOK_CLLONG ||
5972 tok == TOK_CULLONG) {
5973 continue;
5974 } else if (tok >= TOK_UIDENT) {
5975 /* if '& ident [' or '& ident ->', then ident address
5976 is not needed */
5977 t = tok;
5978 next();
5979 if (tok != '[' && tok != TOK_ARROW)
5980 add_var_ref(t);
5981 } else {
5982 level = 0;
5983 while (tok != '}' && tok != ';' &&
5984 !((tok == ',' || tok == ')') && level == 0)) {
5985 if (tok >= TOK_UIDENT) {
5986 add_var_ref(tok);
5987 } else if (tok == '(') {
5988 level++;
5989 } else if (tok == ')') {
5990 level--;
5992 next();
5995 } else {
5996 next();
6000 #endif
6002 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6003 void decl(int l)
6005 int t, b, v, has_init, r;
6006 Sym *sym;
6007 AttributeDef ad;
6009 while (1) {
6010 if (!parse_btype(&b, &ad)) {
6011 /* skip redundant ';' */
6012 /* XXX: find more elegant solution */
6013 if (tok == ';') {
6014 next();
6015 continue;
6017 /* special test for old K&R protos without explicit int
6018 type. Only accepted when defining global data */
6019 if (l == VT_LOCAL || tok < TOK_DEFINE)
6020 break;
6021 b = VT_INT;
6023 if (((b & VT_BTYPE) == VT_ENUM ||
6024 (b & VT_BTYPE) == VT_STRUCT) &&
6025 tok == ';') {
6026 /* we accept no variable after */
6027 next();
6028 continue;
6030 while (1) { /* iterate thru each declaration */
6031 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6032 #if 0
6034 char buf[500];
6035 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6036 printf("type = '%s'\n", buf);
6038 #endif
6039 if (tok == '{') {
6040 #ifdef CONFIG_REG_VARS
6041 TokenString func_str;
6042 ParseState saved_parse_state;
6043 int block_level;
6044 #endif
6046 if (l == VT_LOCAL)
6047 error("cannot use local functions");
6048 if (!(t & VT_FUNC))
6049 expect("function definition");
6051 #ifdef CONFIG_REG_VARS
6052 /* parse all function code and record it */
6054 tok_str_new(&func_str);
6056 block_level = 0;
6057 for(;;) {
6058 int t;
6059 if (tok == -1)
6060 error("unexpected end of file");
6061 tok_str_add_tok(&func_str);
6062 t = tok;
6063 next();
6064 if (t == '{') {
6065 block_level++;
6066 } else if (t == '}') {
6067 block_level--;
6068 if (block_level == 0)
6069 break;
6072 tok_str_add(&func_str, -1);
6073 tok_str_add(&func_str, 0);
6075 save_parse_state(&saved_parse_state);
6077 macro_ptr = func_str.str;
6078 next();
6079 analyse_function();
6080 #endif
6082 /* compute text section */
6083 cur_text_section = ad.section;
6084 if (!cur_text_section)
6085 cur_text_section = text_section;
6086 ind = cur_text_section->data_offset;
6087 funcname = get_tok_str(v, NULL);
6088 sym = sym_find(v);
6089 if (sym) {
6090 /* if symbol is already defined, then put complete type */
6091 sym->t = t;
6092 } else {
6093 /* put function symbol */
6094 sym = sym_push1(&global_stack, v, t, 0);
6096 /* NOTE: we patch the symbol size later */
6097 put_extern_sym(sym, cur_text_section, ind, 0);
6098 func_ind = ind;
6099 sym->r = VT_SYM | VT_CONST;
6100 /* put debug symbol */
6101 if (do_debug)
6102 put_func_debug(sym);
6103 /* push a dummy symbol to enable local sym storage */
6104 sym_push1(&local_stack, 0, 0, 0);
6105 gfunc_prolog(t);
6106 loc = 0;
6107 rsym = 0;
6108 #ifdef CONFIG_REG_VARS
6109 macro_ptr = func_str.str;
6110 next();
6111 #endif
6112 block(NULL, NULL, NULL, NULL, 0);
6113 gsym(rsym);
6114 gfunc_epilog();
6115 cur_text_section->data_offset = ind;
6116 sym_pop(&label_stack, NULL); /* reset label stack */
6117 sym_pop(&local_stack, NULL); /* reset local stack */
6118 /* end of function */
6119 /* patch symbol size */
6120 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
6121 ind - func_ind;
6122 if (do_debug) {
6123 put_stabn(N_FUN, 0, 0, ind - func_ind);
6125 funcname = ""; /* for safety */
6126 func_vt = VT_VOID; /* for safety */
6127 ind = 0; /* for safety */
6129 #ifdef CONFIG_REG_VARS
6130 free(func_str.str);
6131 restore_parse_state(&saved_parse_state);
6132 #endif
6133 break;
6134 } else {
6135 if (b & VT_TYPEDEF) {
6136 /* save typedefed type */
6137 /* XXX: test storage specifiers ? */
6138 sym_push(v, t | VT_TYPEDEF, 0, 0);
6139 } else if ((t & VT_BTYPE) == VT_FUNC) {
6140 /* external function definition */
6141 external_sym(v, t, 0);
6142 } else {
6143 /* not lvalue if array */
6144 r = 0;
6145 if (!(t & VT_ARRAY))
6146 r |= lvalue_type(t);
6147 if (b & VT_EXTERN) {
6148 /* external variable */
6149 external_sym(v, t, r);
6150 } else {
6151 if (t & VT_STATIC)
6152 r |= VT_CONST;
6153 else
6154 r |= l;
6155 has_init = (tok == '=');
6156 if (has_init)
6157 next();
6158 decl_initializer_alloc(t, &ad, r,
6159 has_init, v, l);
6162 if (tok != ',') {
6163 skip(';');
6164 break;
6166 next();
6172 /* compile the C file opened in 'file'. Return non zero if errors. */
6173 static int tcc_compile(TCCState *s)
6175 Sym *define_start;
6176 char buf[512];
6177 int p, section_sym;
6179 funcname = "";
6180 include_stack_ptr = include_stack;
6181 ifdef_stack_ptr = ifdef_stack;
6183 vtop = vstack - 1;
6184 anon_sym = SYM_FIRST_ANOM;
6186 /* file info: full path + filename */
6187 section_sym = 0; /* avoid warning */
6188 if (do_debug) {
6189 section_sym = put_elf_sym(symtab_section, 0, 0,
6190 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
6191 text_section->sh_num, NULL);
6192 getcwd(buf, sizeof(buf));
6193 pstrcat(buf, sizeof(buf), "/");
6194 put_stabs_r(buf, N_SO, 0, 0,
6195 text_section->data_offset, text_section, section_sym);
6196 put_stabs_r(file->filename, N_SO, 0, 0,
6197 text_section->data_offset, text_section, section_sym);
6199 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6200 symbols can be safely used */
6201 put_elf_sym(symtab_section, 0, 0,
6202 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6203 SHN_ABS, file->filename);
6205 /* define common 'char *' type because it is often used internally
6206 for arrays and struct dereference */
6207 char_pointer_type = mk_pointer(VT_BYTE);
6208 /* define an old type function 'int func()' */
6209 p = anon_sym++;
6210 sym_push1(&global_stack, p, 0, FUNC_OLD);
6211 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
6213 define_start = define_stack.top;
6214 inp();
6215 ch = '\n'; /* needed to parse correctly first preprocessor command */
6216 next();
6217 decl(VT_CONST);
6218 if (tok != -1)
6219 expect("declaration");
6221 /* end of translation unit info */
6222 if (do_debug) {
6223 put_stabs_r(NULL, N_SO, 0, 0,
6224 text_section->data_offset, text_section, section_sym);
6227 /* reset define stack, but leave -Dsymbols (may be incorrect if
6228 they are undefined) */
6229 sym_pop(&define_stack, define_start);
6231 sym_pop(&global_stack, NULL);
6233 return 0;
6236 int tcc_compile_string(TCCState *s, const char *str)
6238 BufferedFile bf1, *bf = &bf1;
6239 int ret;
6241 /* init file structure */
6242 bf->fd = -1;
6243 bf->buf_ptr = (char *)str;
6244 bf->buf_end = (char *)str + strlen(bf->buffer);
6245 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6246 bf->line_num = 1;
6247 file = bf;
6249 ret = tcc_compile(s);
6251 /* currently, no need to close */
6252 return ret;
6255 /* define a symbol. A value can also be provided with the '=' operator */
6256 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6258 BufferedFile bf1, *bf = &bf1;
6260 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6261 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6262 /* default value */
6263 if (!value)
6264 value = "1";
6265 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6267 /* init file structure */
6268 bf->fd = -1;
6269 bf->buf_ptr = bf->buffer;
6270 bf->buf_end = bf->buffer + strlen(bf->buffer);
6271 bf->filename[0] = '\0';
6272 bf->line_num = 1;
6273 file = bf;
6275 include_stack_ptr = include_stack;
6277 /* parse with define parser */
6278 inp();
6279 ch = '\n'; /* needed to parse correctly first preprocessor command */
6280 next_nomacro();
6281 parse_define();
6282 file = NULL;
6285 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6287 TokenSym *ts;
6288 Sym *s;
6289 ts = tok_alloc(sym, 0);
6290 s = sym_find1(&define_stack, tok);
6291 /* undefine symbol by putting an invalid name */
6292 if (s)
6293 sym_undef(&define_stack, s);
6296 static int put_elf_str(Section *s, const char *sym)
6298 int offset, len;
6299 char *ptr;
6301 len = strlen(sym) + 1;
6302 offset = s->data_offset;
6303 ptr = section_ptr_add(s, len);
6304 memcpy(ptr, sym, len);
6305 return offset;
6308 /* elf symbol hashing function */
6309 static unsigned long elf_hash(const unsigned char *name)
6311 unsigned long h = 0, g;
6313 while (*name) {
6314 h = (h << 4) + *name++;
6315 g = h & 0xf0000000;
6316 if (g)
6317 h ^= g >> 24;
6318 h &= ~g;
6320 return h;
6323 /* rebuild hash table of section s */
6324 /* NOTE: we do factorize the hash table code to go faster */
6325 static void rebuild_hash(Section *s, unsigned int nb_buckets)
6327 Elf32_Sym *sym;
6328 int *ptr, *hash, nb_syms, sym_index, h;
6329 char *strtab;
6331 strtab = s->link->data;
6332 nb_syms = s->data_offset / sizeof(Elf32_Sym);
6334 s->hash->data_offset = 0;
6335 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
6336 ptr[0] = nb_buckets;
6337 ptr[1] = nb_syms;
6338 ptr += 2;
6339 hash = ptr;
6340 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
6341 ptr += nb_buckets + 1;
6343 sym = (Elf32_Sym *)s->data + 1;
6344 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
6345 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
6346 h = elf_hash(strtab + sym->st_name) % nb_buckets;
6347 *ptr = hash[h];
6348 hash[h] = sym_index;
6349 } else {
6350 *ptr = 0;
6352 ptr++;
6353 sym++;
6357 /* return the symbol number */
6358 static int put_elf_sym(Section *s,
6359 unsigned long value, unsigned long size,
6360 int info, int other, int shndx, const char *name)
6362 int name_offset, sym_index;
6363 int nbuckets, h;
6364 Elf32_Sym *sym;
6365 Section *hs;
6367 sym = section_ptr_add(s, sizeof(Elf32_Sym));
6368 if (name)
6369 name_offset = put_elf_str(s->link, name);
6370 else
6371 name_offset = 0;
6372 /* XXX: endianness */
6373 sym->st_name = name_offset;
6374 sym->st_value = value;
6375 sym->st_size = size;
6376 sym->st_info = info;
6377 sym->st_other = other;
6378 sym->st_shndx = shndx;
6379 sym_index = sym - (Elf32_Sym *)s->data;
6380 hs = s->hash;
6381 if (hs) {
6382 int *ptr, *base;
6383 ptr = section_ptr_add(hs, sizeof(int));
6384 base = (int *)hs->data;
6385 /* only add global or weak symbols */
6386 if (ELF32_ST_BIND(info) != STB_LOCAL) {
6387 /* add another hashing entry */
6388 nbuckets = base[0];
6389 h = elf_hash(name) % nbuckets;
6390 *ptr = base[2 + h];
6391 base[2 + h] = sym_index;
6392 base[1]++;
6393 /* we resize the hash table */
6394 hs->nb_hashed_syms++;
6395 if (hs->nb_hashed_syms > 2 * nbuckets) {
6396 rebuild_hash(s, 2 * nbuckets);
6398 } else {
6399 *ptr = 0;
6400 base[1]++;
6403 return sym_index;
6406 /* find global ELF symbol 'name' and return its index. Return 0 if not
6407 found. */
6408 static int find_elf_sym(Section *s, const char *name)
6410 Elf32_Sym *sym;
6411 Section *hs;
6412 int nbuckets, sym_index, h;
6413 const char *name1;
6415 hs = s->hash;
6416 if (!hs)
6417 return 0;
6418 nbuckets = ((int *)hs->data)[0];
6419 h = elf_hash(name) % nbuckets;
6420 sym_index = ((int *)hs->data)[2 + h];
6421 while (sym_index != 0) {
6422 sym = &((Elf32_Sym *)s->data)[sym_index];
6423 name1 = s->link->data + sym->st_name;
6424 if (!strcmp(name, name1))
6425 return sym_index;
6426 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
6428 return 0;
6431 /* return elf symbol value or error */
6432 static unsigned long get_elf_sym_val(const char *name)
6434 int sym_index;
6435 Elf32_Sym *sym;
6437 sym_index = find_elf_sym(symtab_section, name);
6438 if (!sym_index)
6439 error("%s not defined", name);
6440 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6441 return sym->st_value;
6444 /* add an elf symbol : check if it is already defined and patch
6445 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6446 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
6447 int info, int sh_num, const char *name)
6449 Elf32_Sym *esym;
6450 int sym_bind, sym_index, sym_type, esym_bind;
6452 sym_bind = ELF32_ST_BIND(info);
6453 sym_type = ELF32_ST_TYPE(info);
6455 if (sym_bind != STB_LOCAL) {
6456 /* we search global or weak symbols */
6457 sym_index = find_elf_sym(s, name);
6458 if (!sym_index)
6459 goto do_def;
6460 esym = &((Elf32_Sym *)s->data)[sym_index];
6461 if (esym->st_shndx != SHN_UNDEF) {
6462 esym_bind = ELF32_ST_BIND(esym->st_info);
6463 if (sh_num == SHN_UNDEF) {
6464 /* ignore adding of undefined symbol if the
6465 corresponding symbol is already defined */
6466 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
6467 /* global overrides weak, so patch */
6468 goto do_patch;
6469 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
6470 /* weak is ignored if already global */
6471 } else {
6472 #if 0
6473 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6474 sym_bind, sh_num, esym_bind, esym->st_shndx);
6475 #endif
6476 /* NOTE: we accept that two DLL define the same symbol */
6477 if (s != dynsymtab_section)
6478 error("'%s' defined twice", name);
6480 } else {
6481 do_patch:
6482 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
6483 esym->st_shndx = sh_num;
6484 esym->st_value = value;
6485 esym->st_size = size;
6487 } else {
6488 do_def:
6489 sym_index = put_elf_sym(s, value, size,
6490 ELF32_ST_INFO(sym_bind, sym_type), 0,
6491 sh_num, name);
6493 return sym_index;
6496 /* update sym->c so that it points to an external symbol in section
6497 'section' with value 'value' */
6498 static void put_extern_sym(Sym *sym, Section *section,
6499 unsigned long value, unsigned long size)
6501 int sym_type, sym_bind, sh_num, info;
6502 Elf32_Sym *esym;
6503 const char *name;
6504 char buf[32];
6506 if (section)
6507 sh_num = section->sh_num;
6508 else
6509 sh_num = SHN_UNDEF;
6510 if (!sym->c) {
6511 if ((sym->t & VT_BTYPE) == VT_FUNC)
6512 sym_type = STT_FUNC;
6513 else
6514 sym_type = STT_OBJECT;
6515 if (sym->t & VT_STATIC)
6516 sym_bind = STB_LOCAL;
6517 else
6518 sym_bind = STB_GLOBAL;
6520 name = get_tok_str(sym->v, NULL);
6521 #ifdef CONFIG_TCC_BCHECK
6522 if (do_bounds_check) {
6523 /* if bound checking is activated, we change some function
6524 names by adding the "__bound" prefix */
6525 switch(sym->v) {
6526 case TOK_malloc:
6527 case TOK_free:
6528 case TOK_realloc:
6529 case TOK_memalign:
6530 case TOK_calloc:
6531 case TOK_memcpy:
6532 case TOK_memmove:
6533 case TOK_memset:
6534 case TOK_strlen:
6535 case TOK_strcpy:
6536 strcpy(buf, "__bound_");
6537 strcat(buf, name);
6538 name = buf;
6539 break;
6542 #endif
6543 info = ELF32_ST_INFO(sym_bind, sym_type);
6544 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
6545 } else {
6546 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6547 esym->st_value = value;
6548 esym->st_size = size;
6549 esym->st_shndx = sh_num;
6553 /* put relocation */
6554 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
6555 int type, int symbol)
6557 char buf[256];
6558 Section *sr;
6559 Elf32_Rel *rel;
6561 sr = s->reloc;
6562 if (!sr) {
6563 /* if no relocation section, create it */
6564 snprintf(buf, sizeof(buf), ".rel%s", s->name);
6565 /* if the symtab is allocated, then we consider the relocation
6566 are also */
6567 sr = new_section(buf, SHT_REL, symtab->sh_flags);
6568 sr->sh_entsize = sizeof(Elf32_Rel);
6569 sr->link = symtab;
6570 sr->sh_info = s->sh_num;
6571 s->reloc = sr;
6573 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
6574 rel->r_offset = offset;
6575 rel->r_info = ELF32_R_INFO(symbol, type);
6578 /* put stab debug information */
6580 typedef struct {
6581 unsigned long n_strx; /* index into string table of name */
6582 unsigned char n_type; /* type of symbol */
6583 unsigned char n_other; /* misc info (usually empty) */
6584 unsigned short n_desc; /* description field */
6585 unsigned long n_value; /* value of symbol */
6586 } Stab_Sym;
6588 static void put_stabs(const char *str, int type, int other, int desc,
6589 unsigned long value)
6591 Stab_Sym *sym;
6593 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
6594 if (str) {
6595 sym->n_strx = put_elf_str(stabstr_section, str);
6596 } else {
6597 sym->n_strx = 0;
6599 sym->n_type = type;
6600 sym->n_other = other;
6601 sym->n_desc = desc;
6602 sym->n_value = value;
6605 static void put_stabs_r(const char *str, int type, int other, int desc,
6606 unsigned long value, Section *sec, int sym_index)
6608 put_stabs(str, type, other, desc, value);
6609 put_elf_reloc(symtab_section, stab_section,
6610 stab_section->data_offset - sizeof(unsigned long),
6611 R_DATA_32, sym_index);
6614 static void put_stabn(int type, int other, int desc, int value)
6616 put_stabs(NULL, type, other, desc, value);
6619 static void put_stabd(int type, int other, int desc)
6621 put_stabs(NULL, type, other, desc, 0);
6624 /* In an ELF file symbol table, the local symbols must appear below
6625 the global and weak ones. Since TCC cannot sort it while generating
6626 the code, we must do it after. All the relocation tables are also
6627 modified to take into account the symbol table sorting */
6628 static void sort_syms(Section *s)
6630 int *old_to_new_syms;
6631 Elf32_Sym *new_syms;
6632 int nb_syms, i;
6633 Elf32_Sym *p, *q;
6634 Elf32_Rel *rel, *rel_end;
6635 Section *sr;
6636 int type, sym_index;
6638 nb_syms = s->data_offset / sizeof(Elf32_Sym);
6639 new_syms = malloc(nb_syms * sizeof(Elf32_Sym));
6640 if (!new_syms)
6641 error("memory full");
6642 old_to_new_syms = malloc(nb_syms * sizeof(int));
6643 if (!old_to_new_syms)
6644 error("memory full");
6645 /* first pass for local symbols */
6646 p = (Elf32_Sym *)s->data;
6647 q = new_syms;
6648 for(i = 0; i < nb_syms; i++) {
6649 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
6650 old_to_new_syms[i] = q - new_syms;
6651 *q++ = *p;
6653 p++;
6655 /* save the number of local symbols in section header */
6656 s->sh_info = q - new_syms;
6658 /* then second pass for non local symbols */
6659 p = (Elf32_Sym *)s->data;
6660 for(i = 0; i < nb_syms; i++) {
6661 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
6662 old_to_new_syms[i] = q - new_syms;
6663 *q++ = *p;
6665 p++;
6668 /* we copy the new symbols to the old */
6669 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
6670 free(new_syms);
6672 /* now we modify all the relocations */
6673 for(i = 1; i < nb_sections; i++) {
6674 sr = sections[i];
6675 if (sr->sh_type == SHT_REL && sr->link == s) {
6676 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6677 for(rel = (Elf32_Rel *)sr->data;
6678 rel < rel_end;
6679 rel++) {
6680 sym_index = ELF32_R_SYM(rel->r_info);
6681 type = ELF32_R_TYPE(rel->r_info);
6682 sym_index = old_to_new_syms[sym_index];
6683 rel->r_info = ELF32_R_INFO(sym_index, type);
6688 free(old_to_new_syms);
6691 /* relocate common symbols in the .bss section */
6692 static void relocate_common_syms(void)
6694 Elf32_Sym *sym, *sym_end;
6695 unsigned long offset, align;
6697 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
6698 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6699 sym < sym_end;
6700 sym++) {
6701 if (sym->st_shndx == SHN_COMMON) {
6702 /* align symbol */
6703 align = sym->st_value;
6704 offset = bss_section->data_offset;
6705 offset = (offset + align - 1) & -align;
6706 sym->st_value = offset;
6707 sym->st_shndx = bss_section->sh_num;
6708 offset += sym->st_size;
6709 bss_section->data_offset = offset;
6714 static void *resolve_sym(const char *sym)
6716 return dlsym(NULL, sym);
6719 /* relocate symbol table, resolve undefined symbols if do_resolve is
6720 true and output error if undefined symbol. */
6721 static void relocate_syms(int do_resolve)
6723 Elf32_Sym *sym, *esym, *sym_end;
6724 int sym_bind, sh_num, sym_index;
6725 const char *name;
6726 unsigned long addr;
6728 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
6729 for(sym = (Elf32_Sym *)symtab_section->data + 1;
6730 sym < sym_end;
6731 sym++) {
6732 sh_num = sym->st_shndx;
6733 if (sh_num == SHN_UNDEF) {
6734 name = strtab_section->data + sym->st_name;
6735 if (do_resolve) {
6736 name = symtab_section->link->data + sym->st_name;
6737 addr = (unsigned long)resolve_sym(name);
6738 if (addr) {
6739 sym->st_value = addr;
6740 goto found;
6742 } else if (dynsym) {
6743 /* if dynamic symbol exist, then use it */
6744 sym_index = find_elf_sym(dynsym, name);
6745 if (sym_index) {
6746 esym = &((Elf32_Sym *)dynsym->data)[sym_index];
6747 sym->st_value = esym->st_value;
6748 goto found;
6751 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
6752 it */
6753 if (!strcmp(name, "_fp_hw"))
6754 goto found;
6755 /* only weak symbols are accepted to be undefined. Their
6756 value is zero */
6757 sym_bind = ELF32_ST_BIND(sym->st_info);
6758 if (sym_bind == STB_WEAK) {
6759 sym->st_value = 0;
6760 } else {
6761 error("undefined symbol '%s'", name);
6763 } else if (sh_num < SHN_LORESERVE) {
6764 /* add section base */
6765 sym->st_value += sections[sym->st_shndx]->sh_addr;
6767 found: ;
6771 /* relocate a given section (CPU dependant) */
6772 static void relocate_section(TCCState *s1, Section *s)
6774 Section *sr;
6775 Elf32_Rel *rel, *rel_end, *qrel;
6776 Elf32_Sym *sym;
6777 int type, sym_index, esym_index;
6778 unsigned char *ptr;
6779 unsigned long val, addr;
6781 sr = s->reloc;
6782 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6783 qrel = (Elf32_Rel *)sr->data;
6784 for(rel = qrel;
6785 rel < rel_end;
6786 rel++) {
6787 ptr = s->data + rel->r_offset;
6789 sym_index = ELF32_R_SYM(rel->r_info);
6790 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6791 val = sym->st_value;
6792 type = ELF32_R_TYPE(rel->r_info);
6793 addr = s->sh_addr + rel->r_offset;
6795 /* CPU specific */
6796 switch(type) {
6797 case R_386_32:
6798 if (s1->output_type == TCC_OUTPUT_DLL) {
6799 esym_index = symtab_to_dynsym[sym_index];
6800 qrel->r_offset = rel->r_offset;
6801 if (esym_index) {
6802 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
6803 qrel++;
6804 break;
6805 } else {
6806 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
6807 qrel++;
6810 *(int *)ptr += val;
6811 break;
6812 case R_386_PC32:
6813 if (s1->output_type == TCC_OUTPUT_DLL) {
6814 /* DLL relocation */
6815 esym_index = symtab_to_dynsym[sym_index];
6816 if (esym_index) {
6817 qrel->r_offset = rel->r_offset;
6818 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
6819 qrel++;
6820 break;
6823 *(int *)ptr += val - addr;
6824 break;
6825 case R_386_PLT32:
6826 *(int *)ptr += val - addr;
6827 break;
6828 case R_386_GLOB_DAT:
6829 case R_386_JMP_SLOT:
6830 *(int *)ptr = val;
6831 break;
6832 case R_386_GOTPC:
6833 *(int *)ptr += got->sh_addr - addr;
6834 break;
6835 case R_386_GOTOFF:
6836 *(int *)ptr += val - got->sh_addr;
6837 break;
6838 case R_386_GOT32:
6839 /* we load the got offset */
6840 *(int *)ptr += got_offsets[sym_index];
6841 break;
6844 /* if the relocation is allocated, we change its symbol table */
6845 if (sr->sh_flags & SHF_ALLOC)
6846 sr->link = dynsym;
6849 /* relocate relocation table in 'sr' */
6850 static void relocate_rel(Section *sr)
6852 Section *s;
6853 Elf32_Rel *rel, *rel_end;
6855 s = sections[sr->sh_info];
6856 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6857 for(rel = (Elf32_Rel *)sr->data;
6858 rel < rel_end;
6859 rel++) {
6860 rel->r_offset += s->sh_addr;
6864 /* count the number of dynamic relocations so that we can reserve
6865 their space */
6866 static int prepare_dynamic_rel(Section *sr)
6868 Elf32_Rel *rel, *rel_end;
6869 int sym_index, esym_index, type, count;
6871 count = 0;
6872 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
6873 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
6874 sym_index = ELF32_R_SYM(rel->r_info);
6875 type = ELF32_R_TYPE(rel->r_info);
6876 switch(type) {
6877 case R_386_32:
6878 count++;
6879 break;
6880 case R_386_PC32:
6881 esym_index = symtab_to_dynsym[sym_index];
6882 if (esym_index)
6883 count++;
6884 break;
6885 default:
6886 break;
6889 if (count) {
6890 /* allocate the section */
6891 sr->sh_flags |= SHF_ALLOC;
6892 sr->sh_size = count * sizeof(Elf32_Rel);
6894 return count;
6897 static void put_got_offset(int index, unsigned long val)
6899 int n;
6900 unsigned long *tab;
6902 if (index >= nb_got_offsets) {
6903 /* find immediately bigger power of 2 and reallocate array */
6904 n = 1;
6905 while (index >= n)
6906 n *= 2;
6907 tab = realloc(got_offsets, n * sizeof(unsigned long));
6908 if (!tab)
6909 error("memory full");
6910 got_offsets = tab;
6911 memset(got_offsets + nb_got_offsets, 0,
6912 (n - nb_got_offsets) * sizeof(unsigned long));
6913 nb_got_offsets = n;
6915 got_offsets[index] = val;
6918 /* XXX: suppress that */
6919 static void put32(unsigned char *p, unsigned int val)
6921 p[0] = val;
6922 p[1] = val >> 8;
6923 p[2] = val >> 16;
6924 p[3] = val >> 24;
6927 static void build_got(void)
6929 unsigned char *ptr;
6931 /* if no got, then create it */
6932 got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6933 got->sh_entsize = 4;
6934 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
6935 got->sh_num, "_GLOBAL_OFFSET_TABLE_");
6936 ptr = section_ptr_add(got, 3 * sizeof(int));
6937 /* keep space for _DYNAMIC pointer, if present */
6938 put32(ptr, 0);
6939 /* two dummy got entries */
6940 put32(ptr + 4, 0);
6941 put32(ptr + 8, 0);
6944 /* put a got entry corresponding to a symbol in symtab_section. 'size'
6945 and 'info' can be modifed if more precise info comes from the DLL */
6946 static void put_got_entry(int reloc_type, unsigned long size, int info,
6947 int sym_index)
6949 int index;
6950 const char *name;
6951 Elf32_Sym *sym;
6952 unsigned long offset;
6953 int *ptr;
6955 if (!got)
6956 build_got();
6958 /* if a got entry already exists for that symbol, no need to add one */
6959 if (sym_index < nb_got_offsets &&
6960 got_offsets[sym_index] != 0)
6961 return;
6963 put_got_offset(sym_index, got->data_offset);
6965 if (dynsym) {
6966 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
6967 name = symtab_section->link->data + sym->st_name;
6968 offset = sym->st_value;
6969 /* NOTE: we put temporarily the got offset */
6970 if (reloc_type == R_386_JMP_SLOT) {
6971 nb_plt_entries++;
6972 offset = got->data_offset;
6974 index = put_elf_sym(dynsym, offset,
6975 size, info, 0, sym->st_shndx, name);
6976 /* put a got entry */
6977 put_elf_reloc(dynsym, got,
6978 got->data_offset,
6979 reloc_type, index);
6981 ptr = section_ptr_add(got, sizeof(int));
6982 *ptr = 0;
6985 /* build GOT and PLT entries */
6986 static void build_got_entries(void)
6988 Section *s, *symtab;
6989 Elf32_Rel *rel, *rel_end;
6990 Elf32_Sym *sym;
6991 int i, type, reloc_type, sym_index;
6993 for(i = 1; i < nb_sections; i++) {
6994 s = sections[i];
6995 if (s->sh_type != SHT_REL)
6996 continue;
6997 /* no need to handle got relocations */
6998 if (s->link != symtab_section)
6999 continue;
7000 symtab = s->link;
7001 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
7002 for(rel = (Elf32_Rel *)s->data;
7003 rel < rel_end;
7004 rel++) {
7005 type = ELF32_R_TYPE(rel->r_info);
7006 switch(type) {
7007 case R_386_GOT32:
7008 case R_386_GOTOFF:
7009 case R_386_GOTPC:
7010 case R_386_PLT32:
7011 if (!got)
7012 build_got();
7013 if (type == R_386_GOT32 || type == R_386_PLT32) {
7014 sym_index = ELF32_R_SYM(rel->r_info);
7015 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
7016 /* look at the symbol got offset. If none, then add one */
7017 if (type == R_386_GOT32)
7018 reloc_type = R_386_GLOB_DAT;
7019 else
7020 reloc_type = R_386_JMP_SLOT;
7021 put_got_entry(reloc_type, sym->st_size, sym->st_info,
7022 sym_index);
7024 break;
7025 default:
7026 break;
7032 static Section *new_symtab(const char *symtab_name, int sh_type, int sh_flags,
7033 const char *strtab_name,
7034 const char *hash_name, int hash_sh_flags)
7036 Section *symtab, *strtab, *hash;
7037 int *ptr, nb_buckets;
7039 symtab = new_section(symtab_name, sh_type, sh_flags);
7040 symtab->sh_entsize = sizeof(Elf32_Sym);
7041 strtab = new_section(strtab_name, SHT_STRTAB, sh_flags);
7042 put_elf_str(strtab, "");
7043 symtab->link = strtab;
7044 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
7046 nb_buckets = 1;
7048 hash = new_section(hash_name, SHT_HASH, hash_sh_flags);
7049 hash->sh_entsize = sizeof(int);
7050 symtab->hash = hash;
7051 hash->link = symtab;
7053 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
7054 ptr[0] = nb_buckets;
7055 ptr[1] = 1;
7056 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
7057 return symtab;
7060 /* put dynamic tag */
7061 static void put_dt(Section *dynamic, int dt, unsigned long val)
7063 Elf32_Dyn *dyn;
7064 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
7065 dyn->d_tag = dt;
7066 dyn->d_un.d_val = val;
7069 /* add tcc runtime libraries */
7070 static void tcc_add_runtime(TCCState *s1)
7072 char buf[1024];
7073 unsigned long *ptr;
7074 int i;
7075 Section *s;
7077 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
7078 tcc_add_file(s1, buf);
7079 #ifdef CONFIG_TCC_BCHECK
7080 if (do_bounds_check) {
7081 /* XXX: add an object file to do that */
7082 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
7083 *ptr = 0;
7084 add_elf_sym(symtab_section, 0, 0,
7085 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7086 bounds_section->sh_num, "__bounds_start");
7087 add_elf_sym(symtab_section, (long)&rt_error, 0,
7088 ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
7089 SHN_ABS, "rt_error");
7090 /* add bound check code */
7091 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
7092 tcc_add_file(s1, buf);
7094 #endif
7095 /* add libc if not memory output */
7096 if (s1->output_type != TCC_OUTPUT_MEMORY) {
7097 tcc_add_library(s1, "c");
7098 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
7100 /* add various standard linker symbols */
7101 add_elf_sym(symtab_section,
7102 text_section->data_offset, 0,
7103 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7104 text_section->sh_num, "_etext");
7105 add_elf_sym(symtab_section,
7106 data_section->data_offset, 0,
7107 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7108 data_section->sh_num, "_edata");
7109 add_elf_sym(symtab_section,
7110 bss_section->data_offset, 0,
7111 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7112 bss_section->sh_num, "_end");
7113 /* add start and stop symbols for sections whose name can be
7114 expressed in C */
7115 for(i = 1; i < nb_sections; i++) {
7116 s = sections[i];
7117 if (s->sh_type == SHT_PROGBITS &&
7118 (s->sh_flags & SHF_ALLOC)) {
7119 const char *p;
7120 int ch;
7122 /* check if section name can be expressed in C */
7123 p = s->name;
7124 for(;;) {
7125 ch = *p;
7126 if (!ch)
7127 break;
7128 if (!isid(ch) && !isnum(ch))
7129 goto next_sec;
7130 p++;
7132 snprintf(buf, sizeof(buf), "__start_%s", s->name);
7133 add_elf_sym(symtab_section,
7134 0, 0,
7135 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7136 s->sh_num, buf);
7137 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
7138 add_elf_sym(symtab_section,
7139 s->data_offset, 0,
7140 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7141 s->sh_num, buf);
7143 next_sec: ;
7147 /* add dynamic sections so that the executable is dynamically linked */
7148 static char elf_interp[] = "/lib/ld-linux.so.2";
7150 #define ELF_START_ADDR 0x08048000
7151 #define ELF_PAGE_SIZE 0x1000
7153 /* output an ELF file */
7154 /* XXX: handle realloc'ed sections (instead of mmaping them) */
7155 /* XXX: suppress unneeded sections */
7156 int tcc_output_file(TCCState *s1, const char *filename)
7158 Elf32_Ehdr ehdr;
7159 FILE *f;
7160 int fd, mode;
7161 int *section_order;
7162 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
7163 unsigned long addr;
7164 Section *strsec, *s;
7165 Elf32_Shdr shdr, *sh;
7166 Elf32_Phdr *phdr, *ph;
7167 Section *interp, *plt, *dynamic, *dynstr;
7168 unsigned long saved_dynamic_data_offset;
7169 Elf32_Sym *sym;
7170 int type, file_type;
7171 unsigned long rel_addr, rel_size;
7173 file_type = s1->output_type;
7175 if (file_type != TCC_OUTPUT_OBJ)
7176 tcc_add_runtime(s1);
7178 interp = NULL;
7179 dynamic = NULL;
7180 dynsym = NULL;
7181 got = NULL;
7182 nb_plt_entries = 0;
7183 plt = NULL; /* avoid warning */
7184 dynstr = NULL; /* avoid warning */
7185 saved_dynamic_data_offset = 0; /* avoid warning */
7187 if (file_type != TCC_OUTPUT_OBJ) {
7189 relocate_common_syms();
7191 if (!static_link) {
7192 const char *name;
7193 int sym_index, index;
7194 Elf32_Sym *esym, *sym_end;
7196 if (file_type == TCC_OUTPUT_EXE) {
7197 char *ptr;
7198 /* add interpreter section only if executable */
7199 interp = new_section(".interp", SHT_PROGBITS, SHF_ALLOC);
7200 interp->sh_addralign = 1;
7201 ptr = section_ptr_add(interp, sizeof(elf_interp));
7202 strcpy(ptr, elf_interp);
7205 /* add dynamic symbol table */
7206 dynsym = new_symtab(".dynsym", SHT_DYNSYM, SHF_ALLOC,
7207 ".dynstr",
7208 ".hash", SHF_ALLOC);
7209 dynstr = dynsym->link;
7211 /* add dynamic section */
7212 dynamic = new_section(".dynamic", SHT_DYNAMIC,
7213 SHF_ALLOC | SHF_WRITE);
7214 dynamic->link = dynstr;
7215 dynamic->sh_entsize = sizeof(Elf32_Dyn);
7217 /* add PLT */
7218 plt = new_section(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7219 plt->sh_entsize = 4;
7221 build_got();
7223 /* scan for undefined symbols and see if they are in the
7224 dynamic symbols. If a symbol STT_FUNC is found, then we
7225 add it in the PLT. If a symbol STT_OBJECT is found, we
7226 add it in the .bss section with a suitable relocation */
7227 sym_end = (Elf32_Sym *)(symtab_section->data +
7228 symtab_section->data_offset);
7229 if (file_type == TCC_OUTPUT_EXE) {
7230 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7231 sym < sym_end;
7232 sym++) {
7233 if (sym->st_shndx == SHN_UNDEF) {
7234 name = symtab_section->link->data + sym->st_name;
7235 sym_index = find_elf_sym(dynsymtab_section, name);
7236 if (sym_index) {
7237 esym = &((Elf32_Sym *)dynsymtab_section->data)[sym_index];
7238 type = ELF32_ST_TYPE(esym->st_info);
7239 if (type == STT_FUNC) {
7240 put_got_entry(R_386_JMP_SLOT, esym->st_size,
7241 esym->st_info,
7242 sym - (Elf32_Sym *)symtab_section->data);
7243 } else if (type == STT_OBJECT) {
7244 unsigned long offset;
7245 offset = bss_section->data_offset;
7246 /* XXX: which alignment ? */
7247 offset = (offset + 8 - 1) & -8;
7248 index = put_elf_sym(dynsym, offset, esym->st_size,
7249 esym->st_info, 0,
7250 bss_section->sh_num, name);
7251 put_elf_reloc(dynsym, bss_section,
7252 offset, R_386_COPY, index);
7253 offset += esym->st_size;
7254 bss_section->data_offset = offset;
7256 } else {
7257 /* STB_WEAK undefined symbols are accepted */
7258 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
7259 it */
7260 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
7261 !strcmp(name, "_fp_hw")) {
7262 } else {
7263 error("undefined symbol '%s'", name);
7269 /* now look at unresolved dynamic symbols and export
7270 corresponding symbol */
7271 sym_end = (Elf32_Sym *)(dynsymtab_section->data +
7272 dynsymtab_section->data_offset);
7273 for(esym = (Elf32_Sym *)dynsymtab_section->data + 1;
7274 esym < sym_end;
7275 esym++) {
7276 if (esym->st_shndx == SHN_UNDEF) {
7277 name = dynsymtab_section->link->data + esym->st_name;
7278 sym_index = find_elf_sym(symtab_section, name);
7279 if (sym_index) {
7280 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
7281 put_elf_sym(dynsym, sym->st_value, sym->st_size,
7282 sym->st_info, 0,
7283 sym->st_shndx, name);
7284 } else {
7285 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
7286 /* weak symbols can stay undefined */
7287 } else {
7288 warning("undefined dynamic symbol '%s'", name);
7293 } else {
7294 int nb_syms;
7295 /* shared library case : we simply export all the global symbols */
7296 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
7297 symtab_to_dynsym = malloc(sizeof(int) * nb_syms);
7298 memset(symtab_to_dynsym, 0, sizeof(int) * nb_syms);
7299 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7300 sym < sym_end;
7301 sym++) {
7302 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
7303 name = symtab_section->link->data + sym->st_name;
7304 index = put_elf_sym(dynsym, sym->st_value, sym->st_size,
7305 sym->st_info, 0,
7306 sym->st_shndx, name);
7307 symtab_to_dynsym[sym - (Elf32_Sym *)symtab_section->data] =
7308 index;
7313 build_got_entries();
7315 /* update PLT/GOT sizes so that we can allocate their space */
7316 plt->data_offset += 16 * (nb_plt_entries + 1);
7318 /* add a list of needed dlls */
7319 for(i = 0; i < nb_loaded_dlls; i++) {
7320 DLLReference *dllref = loaded_dlls[i];
7321 if (dllref->level == 0)
7322 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
7324 /* XXX: currently, since we do not handle PIC code, we
7325 must relocate the readonly segments */
7326 if (file_type == TCC_OUTPUT_DLL)
7327 put_dt(dynamic, DT_TEXTREL, 0);
7329 /* add necessary space for other entries */
7330 saved_dynamic_data_offset = dynamic->data_offset;
7331 dynamic->data_offset += 8 * 9;
7332 } else {
7333 /* still need to build got entries in case of static link */
7334 build_got_entries();
7338 memset(&ehdr, 0, sizeof(ehdr));
7340 /* we add a section for symbols */
7341 strsec = new_section(".shstrtab", SHT_STRTAB, 0);
7342 put_elf_str(strsec, "");
7344 /* compute number of sections */
7345 shnum = nb_sections;
7347 /* this array is used to reorder sections in the output file */
7348 section_order = malloc(sizeof(int) * shnum);
7349 if (!section_order)
7350 error("memory full");
7351 section_order[0] = 0;
7352 sh_order_index = 1;
7354 /* compute number of program headers */
7355 switch(file_type) {
7356 default:
7357 case TCC_OUTPUT_OBJ:
7358 phnum = 0;
7359 break;
7360 case TCC_OUTPUT_EXE:
7361 if (!static_link)
7362 phnum = 4;
7363 else
7364 phnum = 2;
7365 break;
7366 case TCC_OUTPUT_DLL:
7367 phnum = 3;
7368 break;
7371 /* allocate strings for section names and decide if an unallocated
7372 section should be output */
7373 /* NOTE: the strsec section comes last, so its size is also
7374 correct ! */
7375 for(i = 1; i < nb_sections; i++) {
7376 s = sections[i];
7377 s->sh_name = put_elf_str(strsec, s->name);
7378 /* when generating a DLL, we include relocations but we may
7379 patch them */
7380 if (file_type == TCC_OUTPUT_DLL &&
7381 s->sh_type == SHT_REL &&
7382 !(s->sh_flags & SHF_ALLOC)) {
7383 prepare_dynamic_rel(s);
7384 } else if (do_debug ||
7385 file_type == TCC_OUTPUT_OBJ ||
7386 (s->sh_flags & SHF_ALLOC) ||
7387 i == (nb_sections - 1)) {
7388 /* we output all sections if debug or object file */
7389 s->sh_size = s->data_offset;
7393 /* allocate program segment headers */
7394 phdr = malloc(phnum * sizeof(Elf32_Phdr));
7395 if (!phdr)
7396 error("memory full");
7397 memset(phdr, 0, phnum * sizeof(Elf32_Phdr));
7399 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
7400 if (phnum > 0) {
7401 /* compute section to program header mapping */
7402 if (file_type == TCC_OUTPUT_DLL)
7403 addr = 0;
7404 else
7405 addr = ELF_START_ADDR;
7407 /* dynamic relocation table information, for .dynamic section */
7408 rel_size = 0;
7409 rel_addr = 0;
7411 /* compute address after headers */
7412 addr += (file_offset & (ELF_PAGE_SIZE - 1));
7414 /* leave one program header for the program interpreter */
7415 ph = &phdr[0];
7416 if (interp)
7417 ph++;
7419 for(j = 0; j < 2; j++) {
7420 ph->p_type = PT_LOAD;
7421 if (j == 0)
7422 ph->p_flags = PF_R | PF_X;
7423 else
7424 ph->p_flags = PF_R | PF_W;
7425 ph->p_align = ELF_PAGE_SIZE;
7427 /* we do the following ordering: interp, symbol tables,
7428 relocations, progbits, nobits */
7429 /* XXX: do faster and simpler sorting */
7430 for(k = 0; k < 5; k++) {
7431 for(i = 1; i < nb_sections; i++) {
7432 s = sections[i];
7433 /* compute if section should be included */
7434 if (j == 0) {
7435 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
7436 SHF_ALLOC)
7437 continue;
7438 } else {
7439 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
7440 (SHF_ALLOC | SHF_WRITE))
7441 continue;
7443 if (s == interp) {
7444 if (k != 0)
7445 continue;
7446 } else if (s->sh_type == SHT_DYNSYM ||
7447 s->sh_type == SHT_STRTAB ||
7448 s->sh_type == SHT_HASH) {
7449 if (k != 1)
7450 continue;
7451 } else if (s->sh_type == SHT_REL) {
7452 if (k != 2)
7453 continue;
7454 } else if (s->sh_type == SHT_NOBITS) {
7455 if (k != 4)
7456 continue;
7457 } else {
7458 if (k != 3)
7459 continue;
7461 section_order[sh_order_index++] = i;
7463 /* section matches: we align it and add its size */
7464 tmp = file_offset;
7465 file_offset = (file_offset + s->sh_addralign - 1) &
7466 ~(s->sh_addralign - 1);
7467 s->sh_offset = file_offset;
7468 addr += file_offset - tmp;
7469 s->sh_addr = addr;
7471 /* update program header infos */
7472 if (ph->p_offset == 0) {
7473 ph->p_offset = file_offset;
7474 ph->p_vaddr = addr;
7475 ph->p_paddr = ph->p_vaddr;
7477 /* update dynamic relocation infos */
7478 if (s->sh_type == SHT_REL) {
7479 if (rel_size == 0)
7480 rel_addr = addr;
7481 rel_size += s->sh_size;
7483 addr += s->sh_size;
7484 if (s->sh_type != SHT_NOBITS)
7485 file_offset += s->sh_size;
7488 ph->p_filesz = file_offset - ph->p_offset;
7489 ph->p_memsz = addr - ph->p_vaddr;
7490 ph++;
7493 /* if interpreter, then add corresponing program header */
7494 if (interp) {
7495 ph = &phdr[0];
7497 ph->p_type = PT_INTERP;
7498 ph->p_offset = interp->sh_offset;
7499 ph->p_vaddr = interp->sh_addr;
7500 ph->p_paddr = ph->p_vaddr;
7501 ph->p_filesz = interp->sh_size;
7502 ph->p_memsz = interp->sh_size;
7503 ph->p_flags = PF_R;
7504 ph->p_align = interp->sh_addralign;
7507 /* if dynamic section, then add corresponing program header */
7508 if (dynamic) {
7509 int plt_offset;
7510 unsigned char *p;
7511 Elf32_Sym *sym_end;
7513 ph = &phdr[phnum - 1];
7515 ph->p_type = PT_DYNAMIC;
7516 ph->p_offset = dynamic->sh_offset;
7517 ph->p_vaddr = dynamic->sh_addr;
7518 ph->p_paddr = ph->p_vaddr;
7519 ph->p_filesz = dynamic->sh_size;
7520 ph->p_memsz = dynamic->sh_size;
7521 ph->p_flags = PF_R | PF_W;
7522 ph->p_align = dynamic->sh_addralign;
7524 /* put GOT dynamic section address */
7525 put32(got->data, dynamic->sh_addr);
7527 /* compute the PLT */
7528 plt->data_offset = 0;
7530 /* first plt entry */
7531 p = section_ptr_add(plt, 16);
7532 p[0] = 0xff; /* pushl got + 4 */
7533 p[1] = 0x35;
7534 put32(p + 2, got->sh_addr + 4);
7535 p[6] = 0xff; /* jmp *(got + 8) */
7536 p[7] = 0x25;
7537 put32(p + 8, got->sh_addr + 8);
7539 /* relocation symbols in .dynsym and build PLT. */
7540 plt_offset = 0;
7541 sym_end = (Elf32_Sym *)(dynsym->data + dynsym->data_offset);
7542 for(sym = (Elf32_Sym *)dynsym->data + 1;
7543 sym < sym_end;
7544 sym++) {
7545 type = ELF32_ST_TYPE(sym->st_info);
7546 if (sym->st_shndx == SHN_UNDEF) {
7547 if (type == STT_FUNC) {
7548 /* one more entry in PLT */
7549 p = section_ptr_add(plt, 16);
7550 p[0] = 0xff; /* jmp *(got + x) */
7551 p[1] = 0x25;
7552 put32(p + 2, got->sh_addr + sym->st_value);
7553 p[6] = 0x68; /* push $xxx */
7554 put32(p + 7, plt_offset);
7555 p[11] = 0xe9; /* jmp plt_start */
7556 put32(p + 12, -(plt->data_offset));
7558 /* patch symbol value to point to plt */
7559 sym->st_value = plt->sh_addr + p - plt->data;
7561 plt_offset += 8;
7563 } else if (sym->st_shndx < SHN_LORESERVE) {
7564 /* do symbol relocation */
7565 sym->st_value += sections[sym->st_shndx]->sh_addr;
7568 /* put dynamic section entries */
7570 dynamic->data_offset = saved_dynamic_data_offset;
7571 put_dt(dynamic, DT_HASH, dynsym->hash->sh_addr);
7572 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
7573 put_dt(dynamic, DT_SYMTAB, dynsym->sh_addr);
7574 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
7575 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
7576 put_dt(dynamic, DT_REL, rel_addr);
7577 put_dt(dynamic, DT_RELSZ, rel_size);
7578 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
7579 put_dt(dynamic, DT_NULL, 0);
7582 ehdr.e_phentsize = sizeof(Elf32_Phdr);
7583 ehdr.e_phnum = phnum;
7584 ehdr.e_phoff = sizeof(Elf32_Ehdr);
7587 /* all other sections come after */
7588 for(i = 1; i < nb_sections; i++) {
7589 s = sections[i];
7590 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
7591 continue;
7592 section_order[sh_order_index++] = i;
7594 file_offset = (file_offset + s->sh_addralign - 1) &
7595 ~(s->sh_addralign - 1);
7596 s->sh_offset = file_offset;
7597 if (s->sh_type != SHT_NOBITS)
7598 file_offset += s->sh_size;
7601 /* if building executable or DLL, then relocate each section
7602 except the GOT which is already relocated */
7603 if (file_type != TCC_OUTPUT_OBJ) {
7604 relocate_syms(0);
7606 /* relocate sections */
7607 /* XXX: ignore sections with allocated relocations ? */
7608 for(i = 1; i < nb_sections; i++) {
7609 s = sections[i];
7610 if (s->reloc && s != got)
7611 relocate_section(s1, s);
7614 /* relocate relocation entries if the relocation tables are
7615 allocated in the executable */
7616 for(i = 1; i < nb_sections; i++) {
7617 s = sections[i];
7618 if ((s->sh_flags & SHF_ALLOC) &&
7619 s->sh_type == SHT_REL) {
7620 relocate_rel(s);
7624 /* get entry point address */
7625 if (file_type == TCC_OUTPUT_EXE)
7626 ehdr.e_entry = get_elf_sym_val("_start");
7627 else
7628 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
7631 sort_syms(symtab_section);
7633 /* align to 4 */
7634 file_offset = (file_offset + 3) & -4;
7636 /* fill header */
7637 ehdr.e_ident[0] = ELFMAG0;
7638 ehdr.e_ident[1] = ELFMAG1;
7639 ehdr.e_ident[2] = ELFMAG2;
7640 ehdr.e_ident[3] = ELFMAG3;
7641 ehdr.e_ident[4] = ELFCLASS32;
7642 ehdr.e_ident[5] = ELFDATA2LSB;
7643 ehdr.e_ident[6] = EV_CURRENT;
7644 switch(file_type) {
7645 default:
7646 case TCC_OUTPUT_EXE:
7647 ehdr.e_type = ET_EXEC;
7648 break;
7649 case TCC_OUTPUT_DLL:
7650 ehdr.e_type = ET_DYN;
7651 break;
7652 case TCC_OUTPUT_OBJ:
7653 ehdr.e_type = ET_REL;
7654 break;
7656 ehdr.e_machine = EM_386;
7657 ehdr.e_version = EV_CURRENT;
7658 ehdr.e_shoff = file_offset;
7659 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
7660 ehdr.e_shentsize = sizeof(Elf32_Shdr);
7661 ehdr.e_shnum = shnum;
7662 ehdr.e_shstrndx = shnum - 1;
7664 /* write elf file */
7665 if (file_type == TCC_OUTPUT_OBJ)
7666 mode = 0666;
7667 else
7668 mode = 0777;
7669 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
7670 if (fd < 0)
7671 error("could not write '%s'", filename);
7673 f = fdopen(fd, "w");
7674 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
7675 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
7676 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
7677 for(i=1;i<nb_sections;i++) {
7678 s = sections[section_order[i]];
7679 if (s->sh_type != SHT_NOBITS) {
7680 while (offset < s->sh_offset) {
7681 fputc(0, f);
7682 offset++;
7684 size = s->sh_size;
7685 fwrite(s->data, 1, size, f);
7686 offset += size;
7689 while (offset < ehdr.e_shoff) {
7690 fputc(0, f);
7691 offset++;
7694 /* output section headers */
7695 for(i=0;i<nb_sections;i++) {
7696 sh = &shdr;
7697 memset(sh, 0, sizeof(Elf32_Shdr));
7698 s = sections[i];
7699 if (s) {
7700 sh->sh_name = s->sh_name;
7701 sh->sh_type = s->sh_type;
7702 sh->sh_flags = s->sh_flags;
7703 sh->sh_entsize = s->sh_entsize;
7704 sh->sh_info = s->sh_info;
7705 if (s->link)
7706 sh->sh_link = s->link->sh_num;
7707 sh->sh_addralign = s->sh_addralign;
7708 sh->sh_addr = s->sh_addr;
7709 sh->sh_offset = s->sh_offset;
7710 sh->sh_size = s->sh_size;
7712 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
7714 fclose(f);
7716 free(section_order);
7717 free(phdr);
7718 return 0;
7721 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
7723 void *data;
7725 data = malloc(size);
7726 if (!data)
7727 error("memory full");
7728 lseek(fd, file_offset, SEEK_SET);
7729 read(fd, data, size);
7730 return data;
7733 typedef struct SectionMergeInfo {
7734 Section *s; /* corresponding existing section */
7735 unsigned long offset; /* offset of the new section in the existing section */
7736 int new_section; /* true if section 's' was added */
7737 } SectionMergeInfo;
7739 /* load an object file and merge it with current files */
7740 /* XXX: handle correctly stab (debug) info */
7741 static int tcc_load_object_file(TCCState *s1,
7742 int fd, unsigned long file_offset)
7744 Elf32_Ehdr ehdr;
7745 Elf32_Shdr *shdr, *sh;
7746 int size, i, j, offset, offseti, nb_syms, sym_index;
7747 unsigned char *strsec, *strtab;
7748 int *old_to_new_syms;
7749 char *sh_name, *name;
7750 SectionMergeInfo *sm_table, *sm;
7751 Elf32_Sym *sym, *symtab;
7752 Elf32_Rel *rel, *rel_end;
7753 Section *s;
7755 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
7756 goto fail;
7757 if (ehdr.e_ident[0] != ELFMAG0 ||
7758 ehdr.e_ident[1] != ELFMAG1 ||
7759 ehdr.e_ident[2] != ELFMAG2 ||
7760 ehdr.e_ident[3] != ELFMAG3)
7761 goto fail;
7762 /* test if object file */
7763 if (ehdr.e_type != ET_REL)
7764 goto fail;
7765 /* test CPU specific stuff */
7766 if (ehdr.e_ident[5] != ELFDATA2LSB ||
7767 ehdr.e_machine != EM_386) {
7768 fail:
7769 error("invalid object file");
7771 /* read sections */
7772 shdr = load_data(fd, file_offset + ehdr.e_shoff,
7773 sizeof(Elf32_Shdr) * ehdr.e_shnum);
7774 sm_table = malloc(sizeof(SectionMergeInfo) * ehdr.e_shnum);
7775 if (!sm_table)
7776 error("memory full");
7777 memset(sm_table, 0, sizeof(SectionMergeInfo) * ehdr.e_shnum);
7779 /* load section names */
7780 sh = &shdr[ehdr.e_shstrndx];
7781 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
7783 /* load symtab and strtab */
7784 symtab = NULL;
7785 strtab = NULL;
7786 nb_syms = 0;
7787 for(i = 1; i < ehdr.e_shnum; i++) {
7788 sh = &shdr[i];
7789 if (sh->sh_type == SHT_SYMTAB) {
7790 if (symtab)
7791 error("object must contain only one symtab");
7792 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
7793 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
7794 sm_table[i].s = symtab_section;
7796 /* now load strtab */
7797 sh = &shdr[sh->sh_link];
7798 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
7802 /* now examine each section and try to merge its content with the
7803 ones in memory */
7804 for(i = 1; i < ehdr.e_shnum; i++) {
7805 /* no need to examine section name strtab */
7806 if (i == ehdr.e_shstrndx)
7807 continue;
7808 sh = &shdr[i];
7809 sh_name = strsec + sh->sh_name;
7810 /* ignore sections types we do not handle */
7811 if (sh->sh_type != SHT_PROGBITS &&
7812 sh->sh_type != SHT_REL &&
7813 sh->sh_type != SHT_NOBITS)
7814 continue;
7815 if (sh->sh_addralign < 1)
7816 sh->sh_addralign = 1;
7817 /* find corresponding section, if any */
7818 for(j = 1; j < nb_sections;j++) {
7819 s = sections[j];
7820 if (!strcmp(s->name, sh_name))
7821 goto found;
7823 /* not found: create new section */
7824 s = new_section(sh_name, sh->sh_type, sh->sh_flags);
7825 /* take as much info as possible from the section. sh_link and
7826 sh_info will be updated later */
7827 s->sh_addralign = sh->sh_addralign;
7828 s->sh_entsize = sh->sh_entsize;
7829 sm_table[i].new_section = 1;
7830 found:
7831 if (sh->sh_type != s->sh_type)
7832 goto fail;
7834 /* align start of section */
7835 offset = s->data_offset;
7836 size = sh->sh_addralign - 1;
7837 offset = (offset + size) & ~size;
7838 if (sh->sh_addralign > s->sh_addralign)
7839 s->sh_addralign = sh->sh_addralign;
7840 s->data_offset = offset;
7841 sm_table[i].offset = offset;
7842 sm_table[i].s = s;
7843 /* concatenate sections */
7844 size = sh->sh_size;
7845 if (sh->sh_type != SHT_NOBITS) {
7846 unsigned char *ptr;
7847 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
7848 ptr = section_ptr(s, size);
7849 read(fd, ptr, size);
7851 s->data_offset += size;
7854 /* second short pass to update sh_link and sh_info fields of new
7855 sections */
7856 sm = sm_table;
7857 for(i = 1; i < ehdr.e_shnum; i++) {
7858 s = sm_table[i].s;
7859 if (!s || !sm_table[i].new_section)
7860 continue;
7861 sh = &shdr[i];
7862 if (sh->sh_link > 0)
7863 s->link = sm_table[sh->sh_link].s;
7864 if (sh->sh_type == SHT_REL) {
7865 s->sh_info = sm_table[sh->sh_info].s->sh_num;
7866 /* update backward link */
7867 sections[s->sh_info]->reloc = s;
7871 /* resolve symbols */
7872 old_to_new_syms = malloc(nb_syms * sizeof(int));
7873 if (!old_to_new_syms)
7874 error("memory full");
7875 memset(old_to_new_syms, 0, nb_syms * sizeof(int));
7876 sym = symtab + 1;
7877 for(i = 1; i < nb_syms; i++, sym++) {
7878 if (sym->st_shndx != SHN_UNDEF &&
7879 sym->st_shndx < SHN_LORESERVE) {
7880 sm = &sm_table[sym->st_shndx];
7881 /* if no corresponding section added, no need to add symbol */
7882 if (!sm->s)
7883 continue;
7884 /* convert section number */
7885 sym->st_shndx = sm->s->sh_num;
7886 /* offset value */
7887 sym->st_value += sm->offset;
7889 /* add symbol */
7890 name = strtab + sym->st_name;
7891 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
7892 sym->st_info, sym->st_shndx, name);
7893 old_to_new_syms[i] = sym_index;
7896 /* third pass to patch relocation entries */
7897 for(i = 1; i < ehdr.e_shnum; i++) {
7898 s = sm_table[i].s;
7899 if (!s)
7900 continue;
7901 sh = &shdr[i];
7902 offset = sm_table[i].offset;
7903 switch(s->sh_type) {
7904 case SHT_REL:
7905 /* take relocation offset information */
7906 offseti = sm_table[sh->sh_info].offset;
7907 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
7908 for(rel = (Elf32_Rel *)(s->data + offset);
7909 rel < rel_end;
7910 rel++) {
7911 int type;
7912 unsigned sym_index;
7913 /* convert symbol index */
7914 type = ELF32_R_TYPE(rel->r_info);
7915 sym_index = ELF32_R_SYM(rel->r_info);
7916 /* NOTE: only one symtab assumed */
7917 if (sym_index >= nb_syms)
7918 goto invalid_reloc;
7919 sym_index = old_to_new_syms[sym_index];
7920 if (!sym_index) {
7921 invalid_reloc:
7922 error("Invalid relocation entry");
7924 rel->r_info = ELF32_R_INFO(sym_index, type);
7925 /* offset the relocation offset */
7926 rel->r_offset += offseti;
7928 break;
7929 default:
7930 break;
7933 free(symtab);
7934 free(strtab);
7935 free(old_to_new_syms);
7936 free(sm_table);
7937 free(shdr);
7938 return 0;
7941 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7943 typedef struct ArchiveHeader {
7944 char ar_name[16]; /* name of this member */
7945 char ar_date[12]; /* file mtime */
7946 char ar_uid[6]; /* owner uid; printed as decimal */
7947 char ar_gid[6]; /* owner gid; printed as decimal */
7948 char ar_mode[8]; /* file mode, printed as octal */
7949 char ar_size[10]; /* file size, printed as decimal */
7950 char ar_fmag[2]; /* should contain ARFMAG */
7951 } ArchiveHeader;
7953 /* load a '.a' file */
7954 static int tcc_load_archive(TCCState *s1, int fd)
7956 ArchiveHeader hdr;
7957 char ar_size[11];
7958 char ar_name[17];
7959 char magic[8];
7960 int size, len, i;
7961 unsigned long file_offset;
7963 /* skip magic which was already checked */
7964 read(fd, magic, sizeof(magic));
7966 for(;;) {
7967 len = read(fd, &hdr, sizeof(hdr));
7968 if (len == 0)
7969 break;
7970 if (len != sizeof(hdr))
7971 error("invalid archive");
7972 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
7973 ar_size[sizeof(hdr.ar_size)] = '\0';
7974 size = strtol(ar_size, NULL, 0);
7975 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
7976 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
7977 if (ar_name[i] != ' ')
7978 break;
7980 ar_name[i + 1] = '\0';
7981 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7982 file_offset = lseek(fd, 0, SEEK_CUR);
7983 if (!strcmp(ar_name, "/") ||
7984 !strcmp(ar_name, "//") ||
7985 !strcmp(ar_name, "__.SYMDEF") ||
7986 !strcmp(ar_name, "__.SYMDEF/") ||
7987 !strcmp(ar_name, "ARFILENAMES/")) {
7988 /* skip symbol table or archive names */
7989 } else {
7990 tcc_load_object_file(s1, fd, file_offset);
7992 /* align to even */
7993 size = (size + 1) & ~1;
7994 lseek(fd, file_offset + size, SEEK_SET);
7996 return 0;
7999 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
8000 is referenced by the user (so it should be added as DT_NEEDED in
8001 the generated ELF file) */
8002 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
8004 Elf32_Ehdr ehdr;
8005 Elf32_Shdr *shdr, *sh, *sh1;
8006 int i, nb_syms, nb_dts, sym_bind;
8007 Elf32_Sym *sym, *dynsym;
8008 Elf32_Dyn *dt, *dynamic;
8009 unsigned char *dynstr;
8010 const char *name, *soname, *p;
8011 DLLReference *dllref;
8013 read(fd, &ehdr, sizeof(ehdr));
8015 /* test CPU specific stuff */
8016 if (ehdr.e_ident[5] != ELFDATA2LSB ||
8017 ehdr.e_machine != EM_386)
8018 error("bad architecture");
8020 /* read sections */
8021 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
8023 /* load dynamic section and dynamic symbols */
8024 nb_syms = 0;
8025 nb_dts = 0;
8026 dynamic = NULL;
8027 dynsym = NULL; /* avoid warning */
8028 dynstr = NULL; /* avoid warning */
8029 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
8030 switch(sh->sh_type) {
8031 case SHT_DYNAMIC:
8032 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
8033 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
8034 break;
8035 case SHT_DYNSYM:
8036 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
8037 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
8038 sh1 = &shdr[sh->sh_link];
8039 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
8040 break;
8041 default:
8042 break;
8046 /* compute the real library name */
8047 soname = filename;
8048 p = strrchr(soname, '/');
8049 if (p)
8050 soname = p + 1;
8052 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
8053 if (dt->d_tag == DT_SONAME) {
8054 soname = dynstr + dt->d_un.d_val;
8058 /* if the dll is already loaded, do not load it */
8059 for(i = 0; i < nb_loaded_dlls; i++) {
8060 dllref = loaded_dlls[i];
8061 if (!strcmp(soname, dllref->name)) {
8062 /* but update level if needed */
8063 if (level < dllref->level)
8064 dllref->level = level;
8065 goto the_end;
8069 // printf("loading dll '%s'\n", soname);
8071 /* add the dll and its level */
8072 dllref = malloc(sizeof(DLLReference) + strlen(soname));
8073 dllref->level = level;
8074 strcpy(dllref->name, soname);
8075 dynarray_add((void ***)&loaded_dlls, &nb_loaded_dlls, dllref);
8077 /* add dynamic symbols in dynsym_section */
8078 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
8079 sym_bind = ELF32_ST_BIND(sym->st_info);
8080 if (sym_bind == STB_LOCAL)
8081 continue;
8082 name = dynstr + sym->st_name;
8083 add_elf_sym(dynsymtab_section, sym->st_value, sym->st_size,
8084 sym->st_info, sym->st_shndx, name);
8087 /* load all referenced DLLs */
8088 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
8089 switch(dt->d_tag) {
8090 case DT_NEEDED:
8091 name = dynstr + dt->d_un.d_val;
8092 for(i = 0; i < nb_loaded_dlls; i++) {
8093 dllref = loaded_dlls[i];
8094 if (!strcmp(name, dllref->name))
8095 goto already_loaded;
8097 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0)
8098 error("referenced dll '%s' not found", name);
8099 already_loaded:
8100 break;
8103 the_end:
8104 free(shdr);
8105 return 0;
8108 /* return -2 if error and CH_EOF if eof */
8109 static void ld_skipspaces(void)
8111 while (ch == ' ' || ch == '\t' || ch == '\n')
8112 cinp();
8115 static int ld_get_cmd(char *cmd, int cmd_size)
8117 char *q;
8119 ld_skipspaces();
8120 if (ch == CH_EOF)
8121 return -1;
8122 q = cmd;
8123 for(;;) {
8124 if (!((ch >= 'a' && ch <= 'z') ||
8125 (ch >= 'A' && ch <= 'Z') ||
8126 (ch >= '0' && ch <= '9') ||
8127 strchr("/.-_+=$:\\,~?*", ch)))
8128 break;
8129 if ((q - cmd) >= (cmd_size - 1))
8130 return -2;
8131 *q++ = ch;
8132 cinp();
8134 *q = '\0';
8135 return 0;
8138 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
8139 files */
8140 static int tcc_load_ldscript(TCCState *s1)
8142 char cmd[64];
8143 char filename[1024];
8144 int ret;
8146 inp();
8147 cinp();
8148 for(;;) {
8149 ret = ld_get_cmd(cmd, sizeof(cmd));
8150 if (ret == CH_EOF)
8151 return 0;
8152 else if (ret < 0)
8153 return -1;
8154 // printf("cmd='%s'\n", cmd);
8155 if (!strcmp(cmd, "INPUT") ||
8156 !strcmp(cmd, "GROUP")) {
8157 ld_skipspaces();
8158 if (ch != '(')
8159 expect("(");
8160 cinp();
8161 for(;;) {
8162 ld_get_cmd(filename, sizeof(filename));
8163 tcc_add_file(s1, filename);
8164 ld_skipspaces();
8165 if (ch == ',') {
8166 cinp();
8167 } else if (ch == ')') {
8168 cinp();
8169 break;
8170 } else if (ch == CH_EOF) {
8171 error("unexpected end of file");
8174 } else {
8175 return -1;
8178 return 0;
8181 /* print the position in the source file of PC value 'pc' by reading
8182 the stabs debug information */
8183 static void rt_printline(unsigned long wanted_pc)
8185 Stab_Sym *sym, *sym_end;
8186 char func_name[128];
8187 unsigned long func_addr, last_pc, pc;
8188 const char *incl_files[INCLUDE_STACK_SIZE];
8189 int incl_index, len, last_line_num, i;
8190 const char *str, *p;
8192 func_name[0] = '\0';
8193 func_addr = 0;
8194 incl_index = 0;
8195 last_pc = 0xffffffff;
8196 last_line_num = 1;
8197 sym = (Stab_Sym *)stab_section->data + 1;
8198 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8199 while (sym < sym_end) {
8200 switch(sym->n_type) {
8201 /* function start or end */
8202 case N_FUN:
8203 if (sym->n_strx == 0) {
8204 func_name[0] = '\0';
8205 func_addr = 0;
8206 } else {
8207 str = stabstr_section->data + sym->n_strx;
8208 p = strchr(str, ':');
8209 if (!p) {
8210 pstrcpy(func_name, sizeof(func_name), str);
8211 } else {
8212 len = p - str;
8213 if (len > sizeof(func_name) - 1)
8214 len = sizeof(func_name) - 1;
8215 memcpy(func_name, str, len);
8216 func_name[len] = '\0';
8218 func_addr = sym->n_value;
8220 break;
8221 /* line number info */
8222 case N_SLINE:
8223 pc = sym->n_value + func_addr;
8224 if (wanted_pc >= last_pc && wanted_pc < pc)
8225 goto found;
8226 last_pc = pc;
8227 last_line_num = sym->n_desc;
8228 break;
8229 /* include files */
8230 case N_BINCL:
8231 str = stabstr_section->data + sym->n_strx;
8232 add_incl:
8233 if (incl_index < INCLUDE_STACK_SIZE) {
8234 incl_files[incl_index++] = str;
8236 break;
8237 case N_EINCL:
8238 if (incl_index > 1)
8239 incl_index--;
8240 break;
8241 case N_SO:
8242 if (sym->n_strx == 0) {
8243 incl_index = 0; /* end of translation unit */
8244 } else {
8245 str = stabstr_section->data + sym->n_strx;
8246 /* do not add path */
8247 len = strlen(str);
8248 if (len > 0 && str[len - 1] != '/')
8249 goto add_incl;
8251 break;
8253 sym++;
8255 /* did not find line number info: */
8256 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
8257 return;
8258 found:
8259 for(i = 0; i < incl_index - 1; i++)
8260 fprintf(stderr, "In file included from %s\n",
8261 incl_files[i]);
8262 if (incl_index > 0) {
8263 fprintf(stderr, "%s:%d: ",
8264 incl_files[incl_index - 1], last_line_num);
8266 if (func_name[0] != '\0') {
8267 fprintf(stderr, "in function '%s()': ", func_name);
8271 /* emit a run time error at position 'pc' */
8272 void rt_error(unsigned long pc, const char *fmt, ...)
8274 va_list ap;
8275 va_start(ap, fmt);
8277 rt_printline(pc);
8278 vfprintf(stderr, fmt, ap);
8279 fprintf(stderr, "\n");
8280 exit(255);
8281 va_end(ap);
8284 #ifndef WIN32
8285 /* signal handler for fatal errors */
8286 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8288 struct ucontext *uc = puc;
8289 unsigned long pc;
8291 #ifdef __i386__
8292 pc = uc->uc_mcontext.gregs[14];
8293 #else
8294 #error please put the right sigcontext field
8295 #endif
8297 switch(signum) {
8298 case SIGFPE:
8299 switch(siginf->si_code) {
8300 case FPE_INTDIV:
8301 case FPE_FLTDIV:
8302 rt_error(pc, "division by zero");
8303 break;
8304 default:
8305 rt_error(pc, "floating point exception");
8306 break;
8308 break;
8309 case SIGBUS:
8310 case SIGSEGV:
8311 rt_error(pc, "dereferencing invalid pointer");
8312 break;
8313 case SIGILL:
8314 rt_error(pc, "illegal instruction");
8315 break;
8316 case SIGABRT:
8317 rt_error(pc, "abort() called");
8318 break;
8319 default:
8320 rt_error(pc, "caught signal %d", signum);
8321 break;
8323 exit(255);
8325 #endif
8327 /* launch the compiled program with the given arguments */
8328 int tcc_run(TCCState *s1, int argc, char **argv)
8330 Section *s;
8331 int (*prog_main)(int, char **);
8332 void (*bound_init)(void);
8333 int i;
8335 tcc_add_runtime(s1);
8337 relocate_common_syms();
8339 /* compute relocation address : section are relocated in place */
8340 for(i = 1; i < nb_sections; i++) {
8341 s = sections[i];
8342 if (s->sh_flags & SHF_ALLOC)
8343 s->sh_addr = (unsigned long)s->data;
8346 relocate_syms(1);
8348 /* relocate each section */
8349 for(i = 1; i < nb_sections; i++) {
8350 s = sections[i];
8351 if (s->reloc)
8352 relocate_section(s1, s);
8355 prog_main = (void *)get_elf_sym_val("main");
8357 if (do_debug) {
8358 #ifdef WIN32
8359 error("debug mode currently not available for Windows");
8360 #else
8361 struct sigaction sigact;
8362 /* install TCC signal handlers to print debug info on fatal
8363 runtime errors */
8364 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
8365 sigact.sa_sigaction = sig_error;
8366 sigemptyset(&sigact.sa_mask);
8367 sigaction(SIGFPE, &sigact, NULL);
8368 sigaction(SIGILL, &sigact, NULL);
8369 sigaction(SIGSEGV, &sigact, NULL);
8370 sigaction(SIGBUS, &sigact, NULL);
8371 sigaction(SIGABRT, &sigact, NULL);
8372 #endif
8375 #ifdef CONFIG_TCC_BCHECK
8376 if (do_bounds_check) {
8377 /* XXX: use .init section so that it also work in binary ? */
8378 bound_init = (void *)get_elf_sym_val("__bound_init");
8379 bound_init();
8381 #endif
8382 return (*prog_main)(argc, argv);
8385 TCCState *tcc_new(void)
8387 char *p, *r;
8388 TCCState *s;
8390 s = malloc(sizeof(TCCState));
8391 if (!s)
8392 return NULL;
8393 s->output_type = TCC_OUTPUT_MEMORY;
8395 /* default include paths */
8396 tcc_add_include_path(s, "/usr/include");
8397 tcc_add_include_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
8398 tcc_add_include_path(s, "/usr/local/include");
8400 /* add all tokens */
8401 tok_ident = TOK_IDENT;
8402 p = tcc_keywords;
8403 while (*p) {
8404 r = p;
8405 while (*r++);
8406 tok_alloc(p, r - p - 1);
8407 p = r;
8410 /* standard defines */
8411 tcc_define_symbol(s, "__STDC__", NULL);
8412 #if defined(TCC_TARGET_I386)
8413 tcc_define_symbol(s, "__i386__", NULL);
8414 #endif
8415 /* tiny C specific defines */
8416 tcc_define_symbol(s, "__TINYC__", NULL);
8418 /* default library paths */
8419 tcc_add_library_path(s, "/usr/local/lib");
8420 tcc_add_library_path(s, "/usr/lib");
8421 tcc_add_library_path(s, "/lib");
8423 /* no section zero */
8424 dynarray_add((void ***)&sections, &nb_sections, NULL);
8426 /* create standard sections */
8427 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8428 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8429 bss_section = new_section(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8431 /* symbols are always generated for linking stage */
8432 symtab_section = new_symtab(".symtab", SHT_SYMTAB, 0,
8433 ".strtab",
8434 ".hashtab", SHF_PRIVATE);
8435 strtab_section = symtab_section->link;
8437 /* private symbol table for dynamic symbols */
8438 dynsymtab_section = new_symtab(".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
8439 ".dynstrtab",
8440 ".dynhashtab", SHF_PRIVATE);
8441 return s;
8444 void tcc_delete(TCCState *s)
8446 free(s);
8449 int tcc_add_include_path(TCCState *s, const char *pathname)
8451 char *pathname1;
8453 pathname1 = strdup(pathname);
8454 if (!pathname1)
8455 return -1;
8456 dynarray_add((void ***)&include_paths, &nb_include_paths, pathname1);
8457 return 0;
8460 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags)
8462 const char *ext;
8463 Elf32_Ehdr ehdr;
8464 int fd;
8465 BufferedFile *saved_file;
8467 /* find source file type with extension */
8468 ext = strrchr(filename, '.');
8469 if (ext)
8470 ext++;
8472 /* open the file */
8473 saved_file = file;
8474 file = tcc_open(filename);
8475 if (!file) {
8476 if (flags & AFF_PRINT_ERROR) {
8477 error("file '%s' not found", filename);
8478 } else {
8479 file = saved_file;
8480 return -1;
8484 if (!ext || !strcmp(ext, "c")) {
8485 /* C file assumed */
8486 tcc_compile(s);
8487 } else {
8488 fd = file->fd;
8489 /* assume executable format: auto guess file type */
8490 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
8491 error("could not read header");
8492 lseek(fd, 0, SEEK_SET);
8494 if (ehdr.e_ident[0] == ELFMAG0 &&
8495 ehdr.e_ident[1] == ELFMAG1 &&
8496 ehdr.e_ident[2] == ELFMAG2 &&
8497 ehdr.e_ident[3] == ELFMAG3) {
8498 file->line_num = 0; /* do not display line number if error */
8499 if (ehdr.e_type == ET_REL) {
8500 tcc_load_object_file(s, fd, 0);
8501 } else if (ehdr.e_type == ET_DYN) {
8502 tcc_load_dll(s, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
8503 } else {
8504 error("unrecognized ELF file");
8506 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8507 file->line_num = 0; /* do not display line number if error */
8508 tcc_load_archive(s, fd);
8509 } else {
8510 /* as GNU ld, consider it is an ld script if not recognized */
8511 if (tcc_load_ldscript(s) < 0)
8512 error("unrecognized file type");
8515 tcc_close(file);
8516 file = saved_file;
8517 return 0;
8520 void tcc_add_file(TCCState *s, const char *filename)
8522 tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8525 int tcc_add_library_path(TCCState *s, const char *pathname)
8527 char *pathname1;
8529 pathname1 = strdup(pathname);
8530 if (!pathname1)
8531 return -1;
8532 dynarray_add((void ***)&library_paths, &nb_library_paths, pathname1);
8533 return 0;
8536 /* find and load a dll. Return non zero if not found */
8537 /* XXX: add '-rpath' option support ? */
8538 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8540 char buf[1024];
8541 int i;
8543 for(i = 0; i < nb_library_paths; i++) {
8544 snprintf(buf, sizeof(buf), "%s/%s",
8545 library_paths[i], filename);
8546 if (tcc_add_file_internal(s, buf, flags) == 0)
8547 return 0;
8549 return -1;
8552 /* the library name is the same as the argument of the '-l' option */
8553 int tcc_add_library(TCCState *s, const char *libraryname)
8555 char buf[1024];
8556 int i;
8557 void *h;
8559 /* if we output to memory, then we simply we dlopen(). */
8560 if (s->output_type == TCC_OUTPUT_MEMORY) {
8561 /* Since the libc is already loaded, we don't need to load it again */
8562 if (!strcmp(libraryname, "c"))
8563 return 0;
8564 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8565 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8566 if (!h)
8567 return -1;
8568 return 0;
8571 /* first we look for the dynamic library if not static linking */
8572 if (!static_link) {
8573 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8574 if (tcc_add_dll(s, buf, 0) == 0)
8575 return 0;
8578 /* then we look for the static library */
8579 for(i = 0; i < nb_library_paths; i++) {
8580 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8581 library_paths[i], libraryname);
8582 if (tcc_add_file_internal(s, buf, 0) == 0)
8583 return 0;
8585 return -1;
8588 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8590 add_elf_sym(symtab_section, val, 0,
8591 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8592 SHN_ABS, name);
8593 return 0;
8596 int tcc_set_output_type(TCCState *s, int output_type)
8598 s->output_type = output_type;
8600 /* if bound checking, then add corresponding sections */
8601 #ifdef CONFIG_TCC_BCHECK
8602 if (do_bounds_check) {
8603 /* define symbol */
8604 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8605 /* create bounds sections */
8606 bounds_section = new_section(".bounds",
8607 SHT_PROGBITS, SHF_ALLOC);
8608 lbounds_section = new_section(".lbounds",
8609 SHT_PROGBITS, SHF_ALLOC);
8611 #endif
8613 /* add debug sections */
8614 if (do_debug) {
8615 /* stab symbols */
8616 stab_section = new_section(".stab", SHT_PROGBITS, 0);
8617 stab_section->sh_entsize = sizeof(Stab_Sym);
8618 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
8619 put_elf_str(stabstr_section, "");
8620 stab_section->link = stabstr_section;
8621 /* put first entry */
8622 put_stabs("", 0, 0, 0, 0);
8625 /* add libc crt1/crti objects */
8626 if (output_type == TCC_OUTPUT_EXE ||
8627 output_type == TCC_OUTPUT_DLL) {
8628 if (output_type != TCC_OUTPUT_DLL)
8629 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8630 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8632 return 0;
8635 #if !defined(LIBTCC)
8637 void help(void)
8639 printf("tcc version 0.9.9 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8640 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8641 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
8642 " [--] infile1 [infile2... --] [infile_args...]\n"
8643 "\n"
8644 "General options:\n"
8645 " -c compile only - generate an object file\n"
8646 " -o outfile set output filename\n"
8647 " -- allows multiples input files if no -o option given. Also\n"
8648 " separate input files from runtime arguments\n"
8649 " -Bdir set tcc internal library path\n"
8650 " -bench output compilation statistics\n"
8651 "Preprocessor options:\n"
8652 " -Idir add include path 'dir'\n"
8653 " -Dsym[=val] define 'sym' with value 'val'\n"
8654 " -Usym undefine 'sym'\n"
8655 "C compiler options:\n"
8656 " -g generate runtime debug info\n"
8657 #ifdef CONFIG_TCC_BCHECK
8658 " -b compile with built-in memory and bounds checker (implies -g)\n"
8659 #endif
8660 "Linker options:\n"
8661 " -Ldir add library path 'dir'\n"
8662 " -llib link with dynamic library 'lib'\n"
8663 " -shared generate a shared library\n"
8664 " -static static linking\n"
8668 int main(int argc, char **argv)
8670 char *r, *outfile;
8671 int optind, output_type, multiple_files, i;
8672 TCCState *s;
8673 char **libraries;
8674 int nb_libraries;
8676 s = tcc_new();
8677 output_type = TCC_OUTPUT_MEMORY;
8679 optind = 1;
8680 outfile = NULL;
8681 multiple_files = 0;
8682 libraries = NULL;
8683 nb_libraries = 0;
8684 while (1) {
8685 if (optind >= argc) {
8686 show_help:
8687 help();
8688 return 1;
8690 r = argv[optind];
8691 if (r[0] != '-')
8692 break;
8693 optind++;
8694 if (r[1] == '-') {
8695 /* '--' enables multiple files input */
8696 multiple_files = 1;
8697 } else if (r[1] == 'h' || r[1] == '?') {
8698 goto show_help;
8699 } else if (r[1] == 'I') {
8700 if (tcc_add_include_path(s, r + 2) < 0)
8701 error("too many include paths");
8702 } else if (r[1] == 'D') {
8703 char *sym, *value;
8704 sym = r + 2;
8705 value = strchr(sym, '=');
8706 if (value) {
8707 *value = '\0';
8708 value++;
8710 tcc_define_symbol(s, sym, value);
8711 } else if (r[1] == 'U') {
8712 tcc_undefine_symbol(s, r + 2);
8713 } else if (r[1] == 'L') {
8714 tcc_add_library_path(s, r + 2);
8715 } else if (r[1] == 'B') {
8716 /* set tcc utilities path (mainly for tcc development) */
8717 tcc_lib_path = r + 2;
8718 } else if (r[1] == 'l') {
8719 dynarray_add((void ***)&libraries, &nb_libraries, r + 2);
8720 } else if (!strcmp(r + 1, "bench")) {
8721 do_bench = 1;
8722 } else
8723 #ifdef CONFIG_TCC_BCHECK
8724 if (r[1] == 'b') {
8725 do_bounds_check = 1;
8726 do_debug = 1;
8727 } else
8728 #endif
8729 if (r[1] == 'g') {
8730 do_debug = 1;
8731 } else if (r[1] == 'c') {
8732 multiple_files = 1;
8733 output_type = TCC_OUTPUT_OBJ;
8734 } else if (!strcmp(r + 1, "static")) {
8735 static_link = 1;
8736 } else if (!strcmp(r + 1, "shared")) {
8737 output_type = TCC_OUTPUT_DLL;
8738 } else if (r[1] == 'o') {
8739 if (optind >= argc)
8740 goto show_help;
8741 multiple_files = 1;
8742 outfile = argv[optind++];
8743 } else {
8744 error("invalid option -- '%s'", r);
8748 /* if outfile provided without other options, we output an
8749 executable */
8750 if (outfile && output_type == TCC_OUTPUT_MEMORY)
8751 output_type = TCC_OUTPUT_EXE;
8753 /* warning if not supported features */
8754 #ifdef CONFIG_TCC_BCHECK
8755 if (do_bounds_check && output_type != TCC_OUTPUT_MEMORY)
8756 warning("bounds checking is currently only supported for in-memory execution");
8757 #endif
8759 tcc_set_output_type(s, output_type);
8761 tcc_add_file(s, argv[optind]);
8762 if (multiple_files) {
8763 while ((optind + 1) < argc) {
8764 optind++;
8765 r = argv[optind];
8766 if (r[0] == '-') {
8767 if (r[1] != '-')
8768 error("'--' expected");
8769 break;
8771 tcc_add_file(s, r);
8775 /* add specified libraries */
8776 for(i = 0; i < nb_libraries;i++) {
8777 if (tcc_add_library(s, libraries[i]) < 0)
8778 error("cannot find -l%s", libraries[i]);
8781 if (do_bench) {
8782 printf("total: %d idents, %d lines, %d bytes\n",
8783 tok_ident - TOK_IDENT, total_lines, total_bytes);
8786 if (s->output_type != TCC_OUTPUT_MEMORY) {
8787 tcc_output_file(s, outfile);
8788 return 0;
8789 } else {
8790 return tcc_run(s, argc - optind, argv + optind);
8794 #endif