2 * TCC - Tiny C Compiler
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.
32 #include <sys/ucontext.h>
37 #ifndef CONFIG_TCC_STATIC
44 /* preprocessor debug */
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
64 /* amount of virtual memory associated to a section (currently, we do
66 #define SECTION_VSIZE (1024 * 1024)
68 #define INCLUDE_STACK_SIZE 32
69 #define IFDEF_STACK_SIZE 64
70 #define VSTACK_SIZE 64
71 #define STRING_MAX_SIZE 1024
72 #define INCLUDE_PATHS_MAX 32
74 #define TOK_HASH_SIZE 2048 /* must be a power of two */
75 #define TOK_ALLOC_INCR 512 /* must be a power of two */
76 #define SYM_HASH_SIZE 1031
77 #define ELF_SYM_HASH_SIZE 2048
78 #define ELF_DYNSYM_HASH_SIZE 32
80 /* token symbol management */
81 typedef struct TokenSym
{
82 struct TokenSym
*hash_next
;
83 int tok
; /* token number */
89 typedef union CValue
{
95 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
97 unsigned long long ull
;
104 typedef struct SValue
{
106 unsigned short r
; /* register + flags */
107 unsigned short r2
; /* second register, used for 'long long'
108 type. If not used, set to VT_CONST */
109 CValue c
; /* constant, if VT_CONST */
112 /* symbol management */
114 int v
; /* symbol token */
115 int t
; /* associated type */
116 int r
; /* associated register */
117 int c
; /* associated number */
118 struct Sym
*next
; /* next related symbol */
119 struct Sym
*prev
; /* prev symbol in stack */
120 struct Sym
*hash_next
; /* next symbol in hash table */
123 typedef struct SymStack
{
125 struct Sym
*hash
[SYM_HASH_SIZE
];
128 /* section definition */
129 /* XXX: use directly ELF structure for parameters ? */
130 /* special flag to indicate that the section should not be linked to
132 #define SHF_PRIVATE 0x80000000
134 typedef struct Section
{
135 unsigned char *data
; /* section data */
136 unsigned char *data_ptr
; /* current data pointer */
137 int sh_name
; /* elf section name (only used during output) */
138 int sh_num
; /* elf section number */
139 int sh_type
; /* elf section type */
140 int sh_flags
; /* elf section flags */
141 int sh_info
; /* elf section info */
142 int sh_addralign
; /* elf section alignment */
143 int sh_entsize
; /* elf entry size */
144 unsigned long sh_size
; /* section size (only used during output) */
145 unsigned long sh_addr
; /* address at which the section is relocated */
146 unsigned long sh_offset
; /* address at which the section is relocated */
147 struct Section
*link
; /* link to another section */
148 struct Section
*reloc
; /* corresponding section for relocation, if any */
149 struct Section
*hash
; /* hash table for symbols */
150 struct Section
*next
;
151 char name
[64]; /* section name */
154 /* GNUC attribute definition */
155 typedef struct AttributeDef
{
158 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
161 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
162 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
163 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
165 /* stored in 'Sym.c' field */
166 #define FUNC_NEW 1 /* ansi function prototype */
167 #define FUNC_OLD 2 /* old function prototype */
168 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
170 /* stored in 'Sym.r' field */
171 #define FUNC_CDECL 0 /* standard c call */
172 #define FUNC_STDCALL 1 /* pascal c call */
174 /* field 'Sym.t' for macros */
175 #define MACRO_OBJ 0 /* object like macro */
176 #define MACRO_FUNC 1 /* function like macro */
178 /* field 'Sym.t' for labels */
179 #define LABEL_FORWARD 1 /* label is forward defined */
181 /* type_decl() types */
182 #define TYPE_ABSTRACT 1 /* type without variable */
183 #define TYPE_DIRECT 2 /* type with variable */
185 #define IO_BUF_SIZE 8192
187 typedef struct BufferedFile
{
188 unsigned char *buf_ptr
;
189 unsigned char *buf_end
;
191 int line_num
; /* current line number - here to simply code */
192 char filename
[1024]; /* current filename - here to simply code */
193 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
196 #define CH_EOB 0 /* end of buffer or '\0' char in file */
197 #define CH_EOF (-1) /* end of file */
199 /* parsing state (used to save parser state to reparse part of the
200 source several times) */
201 typedef struct ParseState
{
208 /* used to record tokens */
209 typedef struct TokenString
{
216 struct BufferedFile
*file
;
217 int ch
, ch1
, tok
, tok1
;
221 /* XXX: suppress first_section */
222 Section
*first_section
, **sections
;
223 int nb_sections
; /* number of sections, including first dummy section */
224 int nb_allocated_sections
;
225 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
226 Section
*cur_text_section
; /* current section where function code is
228 /* bound check related sections */
229 Section
*bounds_section
; /* contains global data bound description */
230 Section
*lbounds_section
; /* contains local data bound description */
231 /* symbol sections */
232 Section
*symtab_section
, *strtab_section
;
235 Section
*stab_section
, *stabstr_section
;
237 /* loc : local variable index
238 ind : output code index
240 anon_sym: anonymous symbol index
243 prog
, ind
, loc
, const_wanted
;
244 int global_expr
; /* true if compound literals must be allocated
245 globally (used during initializers parsing */
246 int func_vt
, func_vc
; /* current function return type (used by
247 return instruction) */
248 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
250 TokenSym
**table_ident
;
251 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
252 char token_buf
[STRING_MAX_SIZE
+ 1];
254 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
256 SValue vstack
[VSTACK_SIZE
], *vtop
;
257 int *macro_ptr
, *macro_ptr_allocated
;
258 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
259 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
260 char *include_paths
[INCLUDE_PATHS_MAX
];
261 int nb_include_paths
;
262 int char_pointer_type
;
264 /* compile with debug symbol (and use them if error during execution) */
267 /* compile with built-in memory and bounds checker */
268 int do_bounds_check
= 0;
270 /* display benchmark infos */
275 /* use GNU C extensions */
278 /* use Tiny C extensions */
281 /* if true, static linking is performed */
288 /* The current value can be: */
289 #define VT_VALMASK 0x00ff
290 #define VT_CONST 0x00f0 /* constant in vc
291 (must be first non register value) */
292 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
293 #define VT_LOCAL 0x00f2 /* offset on stack */
294 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
295 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
296 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
297 #define VT_LVAL 0x0100 /* var is an lvalue */
298 #define VT_SYM 0x0200 /* a symbol value is added */
299 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
300 char/short stored in integer registers) */
301 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
302 dereferencing value */
303 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
304 bounding function call point is in vc */
305 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
306 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
307 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
308 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
311 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
313 #define VT_INT 0 /* integer type */
314 #define VT_BYTE 1 /* signed byte type */
315 #define VT_SHORT 2 /* short type */
316 #define VT_VOID 3 /* void type */
317 #define VT_PTR 4 /* pointer */
318 #define VT_ENUM 5 /* enum definition */
319 #define VT_FUNC 6 /* function type */
320 #define VT_STRUCT 7 /* struct/union definition */
321 #define VT_FLOAT 8 /* IEEE float */
322 #define VT_DOUBLE 9 /* IEEE double */
323 #define VT_LDOUBLE 10 /* IEEE long double */
324 #define VT_BOOL 11 /* ISOC99 boolean type */
325 #define VT_LLONG 12 /* 64 bit integer */
326 #define VT_LONG 13 /* long integer (NEVER USED as type, only
328 #define VT_BTYPE 0x000f /* mask for basic type */
329 #define VT_UNSIGNED 0x0010 /* unsigned type */
330 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
331 #define VT_BITFIELD 0x0040 /* bitfield modifier */
334 #define VT_EXTERN 0x00000080 /* extern definition */
335 #define VT_STATIC 0x00000100 /* static variable */
336 #define VT_TYPEDEF 0x00000200 /* typedef definition */
338 /* type mask (except storage) */
339 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
343 /* warning: the following compare tokens depend on i386 asm code */
355 #define TOK_LAND 0xa0
359 #define TOK_MID 0xa3 /* inc/dec, to void constant */
361 #define TOK_UDIV 0xb0 /* unsigned division */
362 #define TOK_UMOD 0xb1 /* unsigned modulo */
363 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
364 #define TOK_CINT 0xb3 /* number in tokc */
365 #define TOK_CCHAR 0xb4 /* char constant in tokc */
366 #define TOK_STR 0xb5 /* pointer to string in tokc */
367 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
368 #define TOK_LCHAR 0xb7
369 #define TOK_LSTR 0xb8
370 #define TOK_CFLOAT 0xb9 /* float constant */
371 #define TOK_LINENUM 0xba /* line number info */
372 #define TOK_CDOUBLE 0xc0 /* double constant */
373 #define TOK_CLDOUBLE 0xc1 /* long double constant */
374 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
375 #define TOK_ADDC1 0xc3 /* add with carry generation */
376 #define TOK_ADDC2 0xc4 /* add with carry use */
377 #define TOK_SUBC1 0xc5 /* add with carry generation */
378 #define TOK_SUBC2 0xc6 /* add with carry use */
379 #define TOK_CUINT 0xc8 /* unsigned int constant */
380 #define TOK_CLLONG 0xc9 /* long long constant */
381 #define TOK_CULLONG 0xca /* unsigned long long constant */
382 #define TOK_ARROW 0xcb
383 #define TOK_DOTS 0xcc /* three dots */
384 #define TOK_SHR 0xcd /* unsigned shift right */
386 #define TOK_SHL 0x01 /* shift left */
387 #define TOK_SAR 0x02 /* signed shift right */
389 /* assignement operators : normal operator or 0x80 */
390 #define TOK_A_MOD 0xa5
391 #define TOK_A_AND 0xa6
392 #define TOK_A_MUL 0xaa
393 #define TOK_A_ADD 0xab
394 #define TOK_A_SUB 0xad
395 #define TOK_A_DIV 0xaf
396 #define TOK_A_XOR 0xde
397 #define TOK_A_OR 0xfc
398 #define TOK_A_SHL 0x81
399 #define TOK_A_SAR 0x82
401 #define TOK_EOF (-1) /* end of file */
403 /* all identificators and strings have token above that */
404 #define TOK_IDENT 256
425 /* ignored types Must have contiguous values */
431 TOK___SIGNED__
, /* gcc keyword */
434 TOK___INLINE__
, /* gcc keyword */
437 /* unsupported type */
451 /* preprocessor only */
452 TOK_UIDENT
, /* first "user" ident (not keyword) */
453 TOK_DEFINE
= TOK_UIDENT
,
469 /* special identifiers */
472 /* attribute identifiers */
490 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
491 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
492 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
493 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
494 "sizeof\0__attribute__\0"
495 /* the following are not keywords. They are included to ease parsing */
496 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
497 "defined\0undef\0error\0line\0"
498 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
501 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
502 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
503 "noreturn\0__noreturn__\0"
507 #define snprintf _snprintf
510 #if defined(WIN32) || defined(TCC_UCLIBC)
511 /* currently incorrect */
512 long double strtold(const char *nptr
, char **endptr
)
514 return (long double)strtod(nptr
, endptr
);
516 float strtof(const char *nptr
, char **endptr
)
518 return (float)strtod(nptr
, endptr
);
521 /* XXX: need to define this to use them in non ISOC99 context */
522 extern float strtof (const char *__nptr
, char **__endptr
);
523 extern long double strtold (const char *__nptr
, char **__endptr
);
526 char *pstrcpy(char *buf
, int buf_size
, const char *s
);
527 char *pstrcat(char *buf
, int buf_size
, const char *s
);
531 void next_nomacro(void);
532 int expr_const(void);
536 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
537 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
540 void gv2(int rc1
, int rc2
);
541 void move_reg(int r
, int s
);
542 void save_regs(int n
);
543 void save_reg(int r
);
549 void macro_subst(TokenString
*tok_str
,
550 Sym
**nested_list
, int *macro_str
);
551 int save_reg_forced(int r
);
553 void force_charshort_cast(int t
);
554 void gen_cast(int t
);
556 Sym
*sym_find(int v
);
557 Sym
*sym_push(int v
, int t
, int r
, int c
);
560 int type_size(int t
, int *a
);
561 int pointed_type(int t
);
562 int pointed_size(int t
);
563 int is_compatible_types(int t1
, int t2
);
564 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
565 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
567 void error(const char *fmt
, ...);
568 void rt_error(unsigned long pc
, const char *fmt
, ...);
570 void vset(int t
, int r
, int v
);
571 void type_to_str(char *buf
, int buf_size
,
572 int t
, const char *varstr
);
573 char *get_tok_str(int v
, CValue
*cv
);
575 /* section generation */
576 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
);
577 void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
578 static int put_elf_str(Section
*s
, const char *sym
);
579 static int put_elf_sym(Section
*s
,
580 unsigned long value
, unsigned long size
,
581 int info
, int other
, int shndx
, const char *name
);
582 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
583 int type
, int symbol
);
584 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
585 static void put_stabn(int type
, int other
, int desc
, int value
);
586 static void put_stabd(int type
, int other
, int desc
);
588 /* true if float/double/long double type */
589 static inline int is_float(int t
)
593 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
596 #ifdef CONFIG_TCC_BCHECK
600 #ifdef TCC_TARGET_I386
601 #include "i386-gen.c"
607 #ifdef CONFIG_TCC_STATIC
609 #define RTLD_LAZY 0x001
610 #define RTLD_NOW 0x002
611 #define RTLD_GLOBAL 0x100
613 /* dummy function for profiling */
614 void *dlopen(const char *filename
, int flag
)
619 const char *dlerror(void)
624 typedef struct TCCSyms
{
629 #define TCCSYM(a) { #a, &a, },
631 /* add the symbol you want here if no dynamic linking is done */
632 static TCCSyms tcc_syms
[] = {
640 void *dlsym(void *handle
, const char *symbol
)
644 while (p
->str
!= NULL
) {
645 if (!strcmp(p
->str
, symbol
))
654 /********************************************************/
655 /* runtime library is there */
656 /* XXX: we suppose that the host compiler handles 'long long'. It
657 would not be difficult to suppress this assumption */
659 long long __divll(long long a
, long long b
)
664 long long __modll(long long a
, long long b
)
669 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
674 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
679 long long __sardi3(long long a
, int b
)
684 unsigned long long __shrdi3(unsigned long long a
, int b
)
689 long long __shldi3(long long a
, int b
)
694 float __ulltof(unsigned long long a
)
699 double __ulltod(unsigned long long a
)
704 long double __ulltold(unsigned long long a
)
706 return (long double)a
;
709 unsigned long long __ftoull(float a
)
711 return (unsigned long long)a
;
714 unsigned long long __dtoull(double a
)
716 return (unsigned long long)a
;
719 unsigned long long __ldtoull(long double a
)
721 return (unsigned long long)a
;
725 /********************************************************/
727 /* we use our own 'finite' function to avoid potential problems with
728 non standard math libs */
729 /* XXX: endianness dependant */
730 int ieee_finite(double d
)
733 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
736 /* copy a string and truncate it. */
737 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
744 q_end
= buf
+ buf_size
- 1;
756 /* strcat and truncate. */
757 char *pstrcat(char *buf
, int buf_size
, const char *s
)
762 pstrcpy(buf
+ len
, buf_size
- len
, s
);
766 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
768 Section
*sec
, **psec
;
771 sec
= malloc(sizeof(Section
));
773 error("memory full");
774 memset(sec
, 0, sizeof(Section
));
775 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
776 sec
->sh_type
= sh_type
;
777 sec
->sh_flags
= sh_flags
;
784 sec
->sh_addralign
= 4;
787 sec
->sh_addralign
= 1;
790 sec
->sh_addralign
= 32; /* default conservative alignment */
794 /* XXX: currently, a single malloc */
795 data
= malloc(SECTION_VSIZE
);
797 error("could not alloc section '%s'", name
);
799 data
= mmap(NULL
, SECTION_VSIZE
,
800 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
801 MAP_PRIVATE
| MAP_ANONYMOUS
,
803 if (data
== (void *)(-1))
804 error("could not mmap section '%s'", name
);
807 sec
->data_ptr
= data
;
809 if (!(sh_flags
& SHF_PRIVATE
)) {
810 /* only add section if not private */
812 psec
= &first_section
;
813 while (*psec
!= NULL
)
814 psec
= &(*psec
)->next
;
818 if ((nb_sections
+ 1) > nb_allocated_sections
) {
819 if (nb_allocated_sections
== 0)
820 nb_allocated_sections
= 1;
821 nb_allocated_sections
*= 2;
822 sections
= realloc(sections
,
823 nb_allocated_sections
* sizeof(Section
*));
825 error("memory full");
827 sections
[nb_sections
] = sec
;
828 sec
->sh_num
= nb_sections
;
834 /* return a reference to a section, and create it if it does not
836 Section
*find_section(const char *name
)
840 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
841 if (!strcmp(name
, sec
->name
))
844 /* sections are created as PROGBITS */
845 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
848 /* add a new relocation entry to symbol 'sym' in section 's' */
849 void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
852 put_extern_sym(sym
, NULL
, 0);
853 /* now we can add ELF relocation info */
854 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
857 static inline int isid(int c
)
859 return (c
>= 'a' && c
<= 'z') ||
860 (c
>= 'A' && c
<= 'Z') ||
864 static inline int isnum(int c
)
866 return c
>= '0' && c
<= '9';
869 static inline int toup(int c
)
871 if (ch
>= 'a' && ch
<= 'z')
872 return ch
- 'a' + 'A';
881 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
882 fprintf(stderr
, "In file included from %s:%d:\n",
883 (*f
)->filename
, (*f
)->line_num
);
884 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
886 fprintf(stderr
, "tcc: ");
890 void error(const char *fmt
, ...)
895 vfprintf(stderr
, fmt
, ap
);
896 fprintf(stderr
, "\n");
901 void expect(const char *msg
)
903 error("%s expected", msg
);
906 void warning(const char *fmt
, ...)
912 fprintf(stderr
, "warning: ");
913 vfprintf(stderr
, fmt
, ap
);
914 fprintf(stderr
, "\n");
921 error("'%c' expected", c
);
925 void test_lvalue(void)
927 if (!(vtop
->r
& VT_LVAL
))
931 TokenSym
*tok_alloc(const char *str
, int len
)
933 TokenSym
*ts
, **pts
, **ptable
;
940 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
942 pts
= &hash_ident
[h
];
947 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
949 pts
= &(ts
->hash_next
);
952 if (tok_ident
>= SYM_FIRST_ANOM
)
953 error("memory full");
955 /* expand token table if needed */
956 i
= tok_ident
- TOK_IDENT
;
957 if ((i
% TOK_ALLOC_INCR
) == 0) {
958 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
960 error("memory full");
961 table_ident
= ptable
;
964 ts
= malloc(sizeof(TokenSym
) + len
);
966 error("memory full");
968 ts
->tok
= tok_ident
++;
970 ts
->hash_next
= NULL
;
971 memcpy(ts
->str
, str
, len
+ 1);
976 void add_char(char **pp
, int c
)
980 if (c
== '\'' || c
== '\"' || c
== '\\') {
981 /* XXX: could be more precise if char or string */
984 if (c
>= 32 && c
<= 126) {
991 *p
++ = '0' + ((c
>> 6) & 7);
992 *p
++ = '0' + ((c
>> 3) & 7);
993 *p
++ = '0' + (c
& 7);
999 /* XXX: buffer overflow */
1000 char *get_tok_str(int v
, CValue
*cv
)
1002 static char buf
[STRING_MAX_SIZE
+ 1];
1007 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
1008 sprintf(buf
, "%u", cv
->ui
);
1010 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
1013 add_char(&p
, cv
->i
);
1017 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
1021 for(i
=0;i
<ts
->len
;i
++)
1022 add_char(&p
, ts
->str
[i
]);
1026 } else if (v
< TOK_IDENT
) {
1031 } else if (v
< tok_ident
) {
1032 return table_ident
[v
- TOK_IDENT
]->str
;
1033 } else if (v
>= SYM_FIRST_ANOM
) {
1034 /* special name for anonymous symbol */
1035 sprintf(buf
, "L.%u", v
- SYM_FIRST_ANOM
);
1038 /* should never happen */
1043 /* push, without hashing */
1044 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1047 s
= malloc(sizeof(Sym
));
1049 error("memory full");
1060 /* find a symbol and return its associated structure. 's' is the top
1061 of the symbol stack */
1062 Sym
*sym_find2(Sym
*s
, int v
)
1072 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1074 /* find a symbol and return its associated structure. 'st' is the
1076 Sym
*sym_find1(SymStack
*st
, int v
)
1080 s
= st
->hash
[HASH_SYM(v
)];
1089 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1092 s
= sym_push2(&st
->top
, v
, t
, c
);
1093 /* add in hash table */
1095 ps
= &st
->hash
[HASH_SYM(v
)];
1102 /* find a symbol in the right symbol space */
1103 Sym
*sym_find(int v
)
1106 s
= sym_find1(&local_stack
, v
);
1108 s
= sym_find1(&global_stack
, v
);
1112 /* push a given symbol on the symbol stack */
1113 Sym
*sym_push(int v
, int t
, int r
, int c
)
1116 if (local_stack
.top
)
1117 s
= sym_push1(&local_stack
, v
, t
, c
);
1119 s
= sym_push1(&global_stack
, v
, t
, c
);
1124 /* pop symbols until top reaches 'b' */
1125 void sym_pop(SymStack
*st
, Sym
*b
)
1132 /* free hash table entry, except if symbol was freed (only
1133 used for #undef symbols) */
1135 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1142 /* undefined a hashed symbol (used for #undef). Its name is set to
1144 void sym_undef(SymStack
*st
, Sym
*s
)
1147 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1148 while (*ss
!= NULL
) {
1151 ss
= &(*ss
)->hash_next
;
1159 BufferedFile
*tcc_open(const char *filename
)
1164 fd
= open(filename
, O_RDONLY
);
1167 bf
= malloc(sizeof(BufferedFile
));
1173 bf
->buf_ptr
= bf
->buffer
;
1174 bf
->buf_end
= bf
->buffer
;
1175 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1176 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1178 // printf("opening '%s'\n", filename);
1182 void tcc_close(BufferedFile
*bf
)
1184 total_lines
+= bf
->line_num
;
1189 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1190 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1192 /* fill input buffer and return next char */
1193 int tcc_getc_slow(BufferedFile
*bf
)
1196 /* only tries to read if really end of buffer */
1197 if (bf
->buf_ptr
>= bf
->buf_end
) {
1199 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1206 bf
->buf_ptr
= bf
->buffer
;
1207 bf
->buf_end
= bf
->buffer
+ len
;
1208 *bf
->buf_end
= CH_EOB
;
1210 if (bf
->buf_ptr
< bf
->buf_end
) {
1211 return *bf
->buf_ptr
++;
1213 bf
->buf_ptr
= bf
->buf_end
;
1218 /* no need to put that inline */
1219 void handle_eob(void)
1222 ch1
= tcc_getc_slow(file
);
1226 if (include_stack_ptr
== include_stack
)
1228 /* add end of include file debug info */
1230 put_stabd(N_EINCL
, 0, 0);
1232 /* pop include stack */
1234 include_stack_ptr
--;
1235 file
= *include_stack_ptr
;
1239 /* read next char from current input file */
1240 static inline void inp(void)
1242 ch1
= TCC_GETC(file
);
1243 /* end of buffer/file handling */
1248 // printf("ch1=%c 0x%x\n", ch1, ch1);
1251 /* input with '\\n' handling */
1252 static inline void minp(void)
1257 if (ch
== '\\' && ch1
== '\n') {
1261 //printf("ch=%c 0x%x\n", ch, ch);
1265 /* same as minp, but also skip comments */
1273 /* single line C++ comments */
1275 while (ch1
!= '\n' && ch1
!= -1)
1278 ch
= ' '; /* return space */
1279 } else if (ch1
== '*') {
1285 if (c
== '*' && ch1
== '/') {
1287 ch
= ' '; /* return space */
1299 void skip_spaces(void)
1301 while (ch
== ' ' || ch
== '\t')
1305 /* skip block of text until #else, #elif or #endif. skip also pairs of
1307 void preprocess_skip(void)
1312 while (ch
!= '\n') {
1323 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1325 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1327 else if (tok
== TOK_ENDIF
)
1333 /* ParseState handling */
1335 /* XXX: currently, no include file info is stored. Thus, we cannot display
1336 accurate messages if the function or data definition spans multiple
1339 /* save current parse state in 's' */
1340 void save_parse_state(ParseState
*s
)
1342 s
->line_num
= file
->line_num
;
1343 s
->macro_ptr
= macro_ptr
;
1348 /* restore parse state from 's' */
1349 void restore_parse_state(ParseState
*s
)
1351 file
->line_num
= s
->line_num
;
1352 macro_ptr
= s
->macro_ptr
;
1357 /* return the number of additionnal 'ints' necessary to store the
1359 static inline int tok_ext_size(int t
)
1377 return LDOUBLE_SIZE
/ 4;
1383 /* token string handling */
1385 static inline void tok_str_new(TokenString
*s
)
1389 s
->last_line_num
= -1;
1392 static void tok_str_add(TokenString
*s
, int t
)
1398 if ((len
& 63) == 0) {
1399 str
= realloc(str
, (len
+ 64) * sizeof(int));
1408 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1412 n
= tok_ext_size(t
);
1414 tok_str_add(s
, cv
->tab
[i
]);
1417 /* add the current parse token in token string 's' */
1418 static void tok_str_add_tok(TokenString
*s
)
1422 /* save line number info */
1423 if (file
->line_num
!= s
->last_line_num
) {
1424 s
->last_line_num
= file
->line_num
;
1425 cval
.i
= s
->last_line_num
;
1426 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1428 tok_str_add2(s
, tok
, &tokc
);
1431 /* get a token from an integer array and increment pointer accordingly */
1432 static int tok_get(int **tok_str
, CValue
*cv
)
1438 n
= tok_ext_size(t
);
1445 /* eval an expression for #if/#elif */
1446 int expr_preprocess(void)
1456 next(); /* do macro subst */
1457 if (tok
== TOK_DEFINED
) {
1462 c
= sym_find1(&define_stack
, tok
) != 0;
1467 } else if (tok
>= TOK_IDENT
) {
1468 /* if undefined macro */
1472 tok_str_add_tok(&str
);
1474 tok_str_add(&str
, -1); /* simulate end of file */
1475 tok_str_add(&str
, 0);
1476 /* now evaluate C constant expression */
1477 macro_ptr
= str
.str
;
1485 #if defined(DEBUG) || defined(PP_DEBUG)
1486 void tok_print(int *str
)
1492 t
= tok_get(&str
, &cval
);
1495 printf(" %s", get_tok_str(t
, &cval
));
1501 /* parse after #define */
1502 void parse_define(void)
1504 Sym
*s
, *first
, **ps
;
1505 int v
, t
, varg
, is_vaargs
;
1509 /* XXX: should check if same macro (ANSI) */
1512 /* '(' must be just after macro definition for MACRO_FUNC */
1517 while (tok
!= ')') {
1521 if (varg
== TOK_DOTS
) {
1522 varg
= TOK___VA_ARGS__
;
1524 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1528 if (varg
< TOK_IDENT
)
1529 error("badly punctuated parameter list");
1530 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1542 if (ch
== '\n' || ch
== -1)
1545 tok_str_add2(&str
, tok
, &tokc
);
1547 tok_str_add(&str
, 0);
1549 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1552 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1556 void preprocess(void)
1559 char buf
[1024], *q
, *p
;
1567 if (tok
== TOK_DEFINE
) {
1570 } else if (tok
== TOK_UNDEF
) {
1572 s
= sym_find1(&define_stack
, tok
);
1573 /* undefine symbol by putting an invalid name */
1575 sym_undef(&define_stack
, s
);
1576 } else if (tok
== TOK_INCLUDE
) {
1581 } else if (ch
== '\"') {
1586 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1587 if ((q
- buf
) < sizeof(buf
) - 1)
1595 error("#include syntax error");
1596 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1599 /* eat all spaces and comments after include */
1600 /* XXX: slightly incorrect */
1601 while (ch1
!= '\n' && ch1
!= -1)
1604 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1605 error("memory full");
1607 /* first search in current dir if "header.h" */
1609 p
= strrchr(file
->filename
, '/');
1611 size
= p
+ 1 - file
->filename
;
1612 if (size
> sizeof(buf1
) - 1)
1613 size
= sizeof(buf1
) - 1;
1614 memcpy(buf1
, file
->filename
, size
);
1616 pstrcat(buf1
, sizeof(buf1
), buf
);
1621 /* now search in standard include path */
1622 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1623 strcpy(buf1
, include_paths
[i
]);
1630 error("include file '%s' not found", buf
);
1633 /* push current file in stack */
1634 /* XXX: fix current line init */
1635 *include_stack_ptr
++ = file
;
1637 /* add include file debug info */
1639 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1641 } else if (tok
== TOK_IFNDEF
) {
1644 } else if (tok
== TOK_IF
) {
1645 c
= expr_preprocess();
1647 } else if (tok
== TOK_IFDEF
) {
1651 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1653 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1654 error("memory full");
1655 *ifdef_stack_ptr
++ = c
;
1657 } else if (tok
== TOK_ELSE
) {
1658 if (ifdef_stack_ptr
== ifdef_stack
)
1659 error("#else without matching #if");
1660 if (ifdef_stack_ptr
[-1] & 2)
1661 error("#else after #else");
1662 c
= (ifdef_stack_ptr
[-1] ^= 3);
1664 } else if (tok
== TOK_ELIF
) {
1665 if (ifdef_stack_ptr
== ifdef_stack
)
1666 error("#elif without matching #if");
1667 c
= ifdef_stack_ptr
[-1];
1669 error("#elif after #else");
1670 /* last #if/#elif expression was true: we skip */
1673 c
= expr_preprocess();
1674 ifdef_stack_ptr
[-1] = c
;
1681 } else if (tok
== TOK_ENDIF
) {
1682 if (ifdef_stack_ptr
== ifdef_stack
)
1683 error("#endif without matching #if");
1685 } else if (tok
== TOK_LINE
) {
1687 if (tok
!= TOK_CINT
)
1689 file
->line_num
= tokc
.i
;
1695 pstrcpy(file
->filename
, sizeof(file
->filename
),
1696 get_tok_str(tok
, &tokc
));
1698 } else if (tok
== TOK_ERROR
) {
1701 /* ignore other preprocess commands or #! for C scripts */
1702 while (ch
!= '\n' && ch
!= -1)
1706 /* read a number in base b */
1712 if (ch
>= 'a' && ch
<= 'f')
1714 else if (ch
>= 'A' && ch
<= 'F')
1720 if (t
< 0 || t
>= b
)
1728 /* read a character for string or char constant and eval escape codes */
1737 /* at most three octal digits */
1741 c
= c
* 8 + ch
- '0';
1744 c
= c
* 8 + ch
- '0';
1749 } else if (ch
== 'x') {
1767 else if (ch
== 'e' && gnu_ext
)
1769 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1772 error("invalid escaped char");
1779 /* we use 64 bit numbers */
1782 /* bn = (bn << shift) | or_val */
1783 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1787 for(i
=0;i
<BN_SIZE
;i
++) {
1789 bn
[i
] = (v
<< shift
) | or_val
;
1790 or_val
= v
>> (32 - shift
);
1794 void bn_zero(unsigned int *bn
)
1797 for(i
=0;i
<BN_SIZE
;i
++) {
1802 void parse_number(void)
1804 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1806 unsigned int bn
[BN_SIZE
];
1816 /* special dot handling */
1817 if (ch
>= '0' && ch
<= '9') {
1818 goto float_frac_parse
;
1819 } else if (ch
== '.') {
1830 } else if (t
== '0') {
1831 if (ch
== 'x' || ch
== 'X') {
1835 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1841 /* parse all digits. cannot check octal numbers at this stage
1842 because of floating point constants */
1844 if (ch
>= 'a' && ch
<= 'f')
1846 else if (ch
>= 'A' && ch
<= 'F')
1854 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1856 error("number too long");
1862 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1863 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1865 /* NOTE: strtox should support that for hexa numbers, but
1866 non ISOC99 libcs do not support it, so we prefer to do
1868 /* hexadecimal or binary floats */
1869 /* XXX: handle overflows */
1881 } else if (t
>= 'a') {
1883 } else if (t
>= 'A') {
1888 bn_lshift(bn
, shift
, t
);
1895 if (t
>= 'a' && t
<= 'f') {
1897 } else if (t
>= 'A' && t
<= 'F') {
1899 } else if (t
>= '0' && t
<= '9') {
1905 error("invalid digit");
1906 bn_lshift(bn
, shift
, t
);
1911 if (ch
!= 'p' && ch
!= 'P')
1912 error("exponent expected");
1918 } else if (ch
== '-') {
1922 if (ch
< '0' || ch
> '9')
1923 error("exponent digits expected");
1924 while (ch
>= '0' && ch
<= '9') {
1925 exp_val
= exp_val
* 10 + ch
- '0';
1928 exp_val
= exp_val
* s
;
1930 /* now we can generate the number */
1931 /* XXX: should patch directly float number */
1932 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1933 d
= ldexp(d
, exp_val
- frac_bits
);
1938 /* float : should handle overflow */
1940 } else if (t
== 'L') {
1943 /* XXX: not large enough */
1944 tokc
.ld
= (long double)d
;
1950 /* decimal floats */
1952 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1957 while (ch
>= '0' && ch
<= '9') {
1958 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1964 if (ch
== 'e' || ch
== 'E') {
1965 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1969 if (ch
== '-' || ch
== '+') {
1970 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1975 if (ch
< '0' || ch
> '9')
1976 error("exponent digits expected");
1977 while (ch
>= '0' && ch
<= '9') {
1978 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1990 tokc
.f
= strtof(token_buf
, NULL
);
1991 } else if (t
== 'L') {
1994 tokc
.ld
= strtold(token_buf
, NULL
);
1997 tokc
.d
= strtod(token_buf
, NULL
);
2001 unsigned long long n
, n1
;
2004 /* integer number */
2007 if (b
== 10 && *q
== '0') {
2014 /* no need for checks except for base 10 / 8 errors */
2017 } else if (t
>= 'a') {
2019 } else if (t
>= 'A') {
2024 error("invalid digit");
2028 /* detect overflow */
2030 error("integer constant overflow");
2033 /* XXX: not exactly ANSI compliant */
2034 if ((n
& 0xffffffff00000000LL
) != 0) {
2039 } else if (n
> 0x7fffffff) {
2049 error("three 'l' in integer constant");
2052 if (tok
== TOK_CINT
)
2054 else if (tok
== TOK_CUINT
)
2058 } else if (t
== 'U') {
2059 if (tok
== TOK_CINT
)
2061 else if (tok
== TOK_CLLONG
)
2068 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2076 /* return next token without macro substitution */
2077 void next_nomacro1(void)
2085 while (ch
== '\n') {
2087 while (ch
== ' ' || ch
== '\t')
2090 /* preprocessor command if # at start of line after
2095 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2113 while (isid(ch
) || isnum(ch
)) {
2114 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2115 error("ident too long");
2120 ts
= tok_alloc(token_buf
, q
- token_buf
);
2122 } else if (isnum(ch
) || ch
== '.') {
2124 } else if (ch
== '\'') {
2132 } else if (ch
== '\"') {
2137 while (ch
!= '\"') {
2140 error("unterminated string");
2141 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2142 error("string too long");
2146 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2149 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2154 if (*q
== tok
&& q
[1] == ch
) {
2157 /* three chars tests */
2158 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2163 } else if (tok
== TOK_DOTS
) {
2165 error("parse error");
2172 /* single char substitutions */
2175 else if (tok
== '>')
2180 /* return next token without macro substitution. Can read input from
2188 tok
= tok_get(¯o_ptr
, &tokc
);
2189 if (tok
== TOK_LINENUM
) {
2190 file
->line_num
= tokc
.i
;
2199 /* substitute args in macro_str and return allocated string */
2200 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2202 int *st
, last_tok
, t
, notfirst
;
2211 t
= tok_get(¯o_str
, &cval
);
2216 t
= tok_get(¯o_str
, &cval
);
2219 s
= sym_find2(args
, t
);
2221 token_buf
[0] = '\0';
2226 pstrcat(token_buf
, sizeof(token_buf
), " ");
2227 t
= tok_get(&st
, &cval
);
2228 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2232 printf("stringize: %s\n", token_buf
);
2235 ts
= tok_alloc(token_buf
, 0);
2237 tok_str_add2(&str
, TOK_STR
, &cval
);
2239 tok_str_add2(&str
, t
, &cval
);
2241 } else if (t
>= TOK_IDENT
) {
2242 s
= sym_find2(args
, t
);
2245 /* if '##' is present before or after, no arg substitution */
2246 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2247 /* special case for var arg macros : ## eats the
2248 ',' if empty VA_ARGS riable. */
2249 /* XXX: test of the ',' is not 100%
2250 reliable. should fix it to avoid security
2252 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2253 last_tok
== TOK_TWOSHARPS
&&
2254 str
.len
>= 2&& str
.str
[str
.len
- 2] == ',') {
2255 /* suppress ',' '##' */
2259 tok_str_add(&str
, *st
++);
2262 macro_subst(&str
, nested_list
, st
);
2265 tok_str_add(&str
, t
);
2268 tok_str_add2(&str
, t
, &cval
);
2272 tok_str_add(&str
, 0);
2276 /* handle the '##' operator */
2277 int *macro_twosharps(int *macro_str
)
2284 TokenString macro_str1
;
2286 tok_str_new(¯o_str1
);
2292 while (*macro_ptr
== TOK_TWOSHARPS
) {
2294 macro_ptr1
= macro_ptr
;
2297 t
= tok_get(¯o_ptr
, &cval
);
2298 /* XXX: we handle only most common cases:
2299 ident + ident or ident + number */
2300 if (tok
>= TOK_IDENT
&&
2301 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2302 p
= get_tok_str(tok
, &tokc
);
2303 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2304 p
= get_tok_str(t
, &cval
);
2305 pstrcat(token_buf
, sizeof(token_buf
), p
);
2306 ts
= tok_alloc(token_buf
, 0);
2307 tok
= ts
->tok
; /* modify current token */
2309 /* cannot merge tokens: skip '##' */
2310 macro_ptr
= macro_ptr1
;
2315 tok_str_add2(¯o_str1
, tok
, &tokc
);
2317 tok_str_add(¯o_str1
, 0);
2318 return macro_str1
.str
;
2321 /* do macro substitution of macro_str and add result to
2322 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2323 substituted. 'nested_list' is the list of all macros we got inside
2324 to avoid recursing. */
2325 void macro_subst(TokenString
*tok_str
,
2326 Sym
**nested_list
, int *macro_str
)
2328 Sym
*s
, *args
, *sa
, *sa1
;
2329 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2330 int mstr_allocated
, *macro_str1
;
2334 saved_macro_ptr
= macro_ptr
;
2335 macro_ptr
= macro_str
;
2338 /* first scan for '##' operator handling */
2339 macro_str1
= macro_twosharps(macro_str
);
2340 macro_ptr
= macro_str1
;
2347 /* special macros */
2348 if (tok
== TOK___LINE__
) {
2349 cval
.i
= file
->line_num
;
2350 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2351 } else if (tok
== TOK___FILE__
) {
2352 cval
.ts
= tok_alloc(file
->filename
, 0);
2353 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2354 } else if (tok
== TOK___DATE__
) {
2355 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2356 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2357 } else if (tok
== TOK___TIME__
) {
2358 cval
.ts
= tok_alloc("00:00:00", 0);
2359 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2360 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2361 /* if symbol is a macro, prepare substitution */
2362 /* if nested substitution, do nothing */
2363 if (sym_find2(*nested_list
, tok
))
2367 if (s
->t
== MACRO_FUNC
) {
2368 /* NOTE: we do not use next_nomacro to avoid eating the
2369 next token. XXX: find better solution */
2373 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2377 if (t
!= '(') /* no macro subst */
2380 /* argument macro */
2385 /* NOTE: empty args are allowed, except if no args */
2387 /* handle '()' case */
2388 if (!args
&& tok
== ')')
2391 error("macro '%s' used with too many args",
2392 get_tok_str(s
->v
, 0));
2395 /* NOTE: non zero sa->t indicates VA_ARGS */
2396 while ((parlevel
> 0 ||
2398 (tok
!= ',' || sa
->t
))) &&
2402 else if (tok
== ')')
2404 tok_str_add2(&str
, tok
, &tokc
);
2407 tok_str_add(&str
, 0);
2408 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2411 /* special case for gcc var args: add an empty
2412 var arg argument if it is omitted */
2413 if (sa
&& sa
->t
&& gnu_ext
)
2423 error("macro '%s' used with too few args",
2424 get_tok_str(s
->v
, 0));
2427 /* now subst each arg */
2428 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2439 sym_push2(nested_list
, s
->v
, 0, 0);
2440 macro_subst(tok_str
, nested_list
, mstr
);
2441 /* pop nested defined symbol */
2443 *nested_list
= sa1
->prev
;
2449 /* no need to add if reading input stream */
2452 tok_str_add2(tok_str
, tok
, &tokc
);
2454 /* only replace one macro while parsing input stream */
2458 macro_ptr
= saved_macro_ptr
;
2463 /* return next token with macro substitution */
2469 /* special 'ungettok' case for label parsing */
2477 /* if not reading from macro substituted string, then try
2479 /* XXX: optimize non macro case */
2482 macro_subst(&str
, &nested_list
, NULL
);
2484 tok_str_add(&str
, 0);
2485 macro_ptr
= str
.str
;
2486 macro_ptr_allocated
= str
.str
;
2494 /* end of macro string: free it */
2495 free(macro_ptr_allocated
);
2502 printf("token = %s\n", get_tok_str(tok
, tokc
));
2506 void swap(int *p
, int *q
)
2514 void vsetc(int t
, int r
, CValue
*vc
)
2516 if (vtop
>= vstack
+ VSTACK_SIZE
)
2517 error("memory full");
2518 /* cannot let cpu flags if other instruction are generated */
2519 /* XXX: VT_JMP test too ? */
2520 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2525 vtop
->r2
= VT_CONST
;
2529 /* push integer constant */
2534 vsetc(VT_INT
, VT_CONST
, &cval
);
2537 /* push a reference to a section offset by adding a dummy symbol */
2538 void vpush_ref(int t
, Section
*sec
, unsigned long offset
)
2545 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2546 sym
->r
= VT_CONST
| VT_SYM
;
2547 put_extern_sym(sym
, sec
, offset
);
2549 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2552 void vset(int t
, int r
, int v
)
2569 void vpushv(SValue
*v
)
2571 if (vtop
>= vstack
+ VSTACK_SIZE
)
2572 error("memory full");
2582 /* save r to the memory stack, and mark it as being free */
2583 void save_reg(int r
)
2585 int l
, i
, saved
, t
, size
, align
;
2588 /* modify all stack values */
2591 for(p
=vstack
;p
<=vtop
;p
++) {
2592 i
= p
->r
& VT_VALMASK
;
2593 if ((p
->r
& VT_VALMASK
) == r
||
2594 (p
->r2
& VT_VALMASK
) == r
) {
2595 /* must save value on stack if not already done */
2597 /* store register in the stack */
2599 if ((p
->r
& VT_LVAL
) ||
2600 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2602 size
= type_size(t
, &align
);
2603 loc
= (loc
- size
) & -align
;
2605 sv
.r
= VT_LOCAL
| VT_LVAL
;
2608 #ifdef TCC_TARGET_I386
2609 /* x86 specific: need to pop fp register ST0 if saved */
2611 o(0xd9dd); /* fstp %st(1) */
2614 /* special long long case */
2615 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2622 /* mark that stack entry as being saved on the stack */
2634 /* find a free register of class 'rc'. If none, save one register */
2640 /* find a free register */
2641 for(r
=0;r
<NB_REGS
;r
++) {
2642 if (reg_classes
[r
] & rc
) {
2643 for(p
=vstack
;p
<=vtop
;p
++) {
2644 if ((p
->r
& VT_VALMASK
) == r
||
2645 (p
->r2
& VT_VALMASK
) == r
)
2653 /* no register left : free the first one on the stack (VERY
2654 IMPORTANT to start from the bottom to ensure that we don't
2655 spill registers used in gen_opi()) */
2656 for(p
=vstack
;p
<=vtop
;p
++) {
2657 r
= p
->r
& VT_VALMASK
;
2658 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2666 /* save registers up to (vtop - n) stack entry */
2667 void save_regs(int n
)
2672 for(p
= vstack
;p
<= p1
; p
++) {
2673 r
= p
->r
& VT_VALMASK
;
2680 /* move register 's' to 'r', and flush previous value of r to memory
2682 void move_reg(int r
, int s
)
2695 /* get address of vtop (vtop MUST BE an lvalue) */
2698 vtop
->r
&= ~VT_LVAL
;
2699 /* tricky: if saved lvalue, then we can go back to lvalue */
2700 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2701 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2704 #ifdef CONFIG_TCC_BCHECK
2705 /* generate lvalue bound code */
2710 vtop
->r
&= ~VT_MUSTBOUND
;
2711 /* if lvalue, then use checking code before dereferencing */
2712 if (vtop
->r
& VT_LVAL
) {
2713 /* if not VT_BOUNDED value, then make one */
2714 if (!(vtop
->r
& VT_BOUNDED
)) {
2715 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2718 gen_bounded_ptr_add();
2719 vtop
->r
|= lval_type
;
2721 /* then check for dereferencing */
2722 gen_bounded_ptr_deref();
2727 /* store vtop a register belonging to class 'rc'. lvalues are
2728 converted to values. Cannot be used if cannot be converted to
2729 register value (such as structures). */
2732 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2733 unsigned long long ll
;
2735 /* NOTE: get_reg can modify vstack[] */
2736 if (vtop
->t
& VT_BITFIELD
) {
2737 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2738 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2739 /* remove bit field info to avoid loops */
2740 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2741 /* generate shifts */
2742 vpushi(32 - (bit_pos
+ bit_size
));
2744 vpushi(32 - bit_size
);
2745 /* NOTE: transformed to SHR if unsigned */
2749 if (is_float(vtop
->t
) &&
2750 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2754 /* XXX: unify with initializers handling ? */
2755 /* CPUs usually cannot use float constants, so we store them
2756 generically in data segment */
2757 size
= type_size(vtop
->t
, &align
);
2758 data_offset
= data_section
->data_ptr
- data_section
->data
;
2759 data_offset
= (data_offset
+ align
- 1) & -align
;
2760 /* XXX: not portable yet */
2763 ((int *)(data_section
->data
+ data_offset
))[i
] = vtop
->c
.tab
[i
];
2766 sym
= sym_push1(&global_stack
, v
, vtop
->t
| VT_STATIC
, 0);
2767 sym
->r
= VT_CONST
| VT_SYM
;
2768 put_extern_sym(sym
, data_section
, data_offset
);
2770 vtop
->r
|= VT_LVAL
| VT_SYM
;
2772 data_offset
+= size
<< 2;
2773 data_section
->data_ptr
= data_section
->data
+ data_offset
;
2775 #ifdef CONFIG_TCC_BCHECK
2776 if (vtop
->r
& VT_MUSTBOUND
)
2780 r
= vtop
->r
& VT_VALMASK
;
2781 /* need to reload if:
2783 - lvalue (need to dereference pointer)
2784 - already a register, but not in the right class */
2785 if (r
>= VT_CONST
||
2786 (vtop
->r
& VT_LVAL
) ||
2787 !(reg_classes
[r
] & rc
) ||
2788 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2789 !(reg_classes
[vtop
->r2
] & rc
))) {
2791 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2792 /* two register type load : expand to two words
2794 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2797 vtop
->c
.ui
= ll
; /* first word */
2799 vtop
->r
= r
; /* save register value */
2800 vpushi(ll
>> 32); /* second word */
2801 } else if (r
>= VT_CONST
||
2802 (vtop
->r
& VT_LVAL
)) {
2803 /* load from memory */
2806 vtop
[-1].r
= r
; /* save register value */
2807 /* increment pointer to get second word */
2814 /* move registers */
2817 vtop
[-1].r
= r
; /* save register value */
2818 vtop
->r
= vtop
[-1].r2
;
2820 /* allocate second register */
2827 /* write second register */
2829 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2831 /* lvalue of scalar type : need to use lvalue type
2832 because of possible cast */
2835 /* compute memory access type */
2836 if (vtop
->r
& VT_LVAL_BYTE
)
2838 else if (vtop
->r
& VT_LVAL_SHORT
)
2840 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2844 /* restore wanted type */
2847 /* one register type load */
2856 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2857 void gv2(int rc1
, int rc2
)
2859 /* generate more generic register first */
2865 /* test if reload is needed for first register */
2866 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2876 /* test if reload is needed for first register */
2877 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2883 /* expand long long on stack in two int registers */
2888 u
= vtop
->t
& VT_UNSIGNED
;
2891 vtop
[0].r
= vtop
[-1].r2
;
2892 vtop
[0].r2
= VT_CONST
;
2893 vtop
[-1].r2
= VT_CONST
;
2894 vtop
[0].t
= VT_INT
| u
;
2895 vtop
[-1].t
= VT_INT
| u
;
2898 /* build a long long from two ints */
2901 gv2(RC_INT
, RC_INT
);
2902 vtop
[-1].r2
= vtop
[0].r
;
2907 /* rotate n first stack elements to the bottom */
2914 for(i
=-n
+1;i
!=0;i
++)
2915 vtop
[i
] = vtop
[i
+1];
2919 /* pop stack value */
2923 v
= vtop
->r
& VT_VALMASK
;
2924 #ifdef TCC_TARGET_I386
2925 /* for x86, we need to pop the FP stack */
2927 o(0xd9dd); /* fstp %st(1) */
2930 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2931 /* need to put correct jump if && or || without test */
2937 /* convert stack entry to register and duplicate its value in another
2945 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2952 /* stack: H L L1 H1 */
2960 /* duplicate value */
2971 load(r1
, &sv
); /* move r to r1 */
2973 /* duplicates value */
2978 /* generate CPU independent (unsigned) long long operations */
2979 void gen_opl(int op
)
2981 int t
, a
, b
, op1
, c
, i
;
3000 /* call generic long long function */
3001 gfunc_start(&gf
, FUNC_CDECL
);
3008 vtop
->r2
= REG_LRET
;
3021 /* stack: L1 H1 L2 H2 */
3026 vtop
[-2] = vtop
[-3];
3029 /* stack: H1 H2 L1 L2 */
3035 /* stack: H1 H2 L1 L2 ML MH */
3038 /* stack: ML MH H1 H2 L1 L2 */
3042 /* stack: ML MH H1 L2 H2 L1 */
3047 /* stack: ML MH M1 M2 */
3050 } else if (op
== '+' || op
== '-') {
3051 /* XXX: add non carry method too (for MIPS or alpha) */
3057 /* stack: H1 H2 (L1 op L2) */
3060 gen_op(op1
+ 1); /* TOK_xxxC2 */
3063 /* stack: H1 H2 (L1 op L2) */
3066 /* stack: (L1 op L2) H1 H2 */
3068 /* stack: (L1 op L2) (H1 op H2) */
3076 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3081 /* stack: L H shift */
3083 /* constant: simpler */
3084 /* NOTE: all comments are for SHL. the other cases are
3085 done by swaping words */
3096 if (op
!= TOK_SAR
) {
3126 /* XXX: should provide a faster fallback on x86 ? */
3141 /* compare operations */
3147 /* stack: L1 H1 L2 H2 */
3149 vtop
[-1] = vtop
[-2];
3151 /* stack: L1 L2 H1 H2 */
3154 /* when values are equal, we need to compare low words. since
3155 the jump is inverted, we invert the test too. */
3158 else if (op1
== TOK_GT
)
3160 else if (op1
== TOK_ULT
)
3162 else if (op1
== TOK_UGT
)
3167 if (op1
!= TOK_NE
) {
3171 /* generate non equal test */
3172 /* XXX: NOT PORTABLE yet */
3176 #ifdef TCC_TARGET_I386
3177 b
= psym(0x850f, 0);
3179 error("not implemented");
3187 vset(VT_INT
, VT_JMPI
, a
);
3192 /* handle integer constant optimizations and various machine
3194 void gen_opic(int op
)
3201 /* currently, we cannot do computations with forward symbols */
3202 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3203 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3207 case '+': v1
->c
.i
+= fc
; break;
3208 case '-': v1
->c
.i
-= fc
; break;
3209 case '&': v1
->c
.i
&= fc
; break;
3210 case '^': v1
->c
.i
^= fc
; break;
3211 case '|': v1
->c
.i
|= fc
; break;
3212 case '*': v1
->c
.i
*= fc
; break;
3219 /* if division by zero, generate explicit division */
3222 error("division by zero in constant");
3226 default: v1
->c
.i
/= fc
; break;
3227 case '%': v1
->c
.i
%= fc
; break;
3228 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3229 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3232 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3233 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3234 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3236 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3237 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3238 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3239 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3240 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3241 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3242 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3243 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3244 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3245 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3247 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3248 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3254 /* if commutative ops, put c2 as constant */
3255 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3256 op
== '|' || op
== '*')) {
3261 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3264 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3265 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3271 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3272 /* try to use shifts instead of muls or divs */
3273 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3282 else if (op
== TOK_PDIV
)
3290 /* call low level op generator */
3296 /* generate a floating point operation with constant propagation */
3297 void gen_opif(int op
)
3305 /* currently, we cannot do computations with forward symbols */
3306 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3307 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3309 if (v1
->t
== VT_FLOAT
) {
3312 } else if (v1
->t
== VT_DOUBLE
) {
3320 /* NOTE: we only do constant propagation if finite number (not
3321 NaN or infinity) (ANSI spec) */
3322 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3326 case '+': f1
+= f2
; break;
3327 case '-': f1
-= f2
; break;
3328 case '*': f1
*= f2
; break;
3332 error("division by zero in constant");
3337 /* XXX: also handles tests ? */
3341 /* XXX: overflow test ? */
3342 if (v1
->t
== VT_FLOAT
) {
3344 } else if (v1
->t
== VT_DOUBLE
) {
3357 int pointed_size(int t
)
3359 return type_size(pointed_type(t
), &t
);
3363 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3365 char buf1
[256], buf2
[256];
3369 if (!is_compatible_types(t1
, t2
)) {
3370 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3371 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3372 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3377 /* generic gen_op: handles types problems */
3380 int u
, t1
, t2
, bt1
, bt2
, t
;
3384 bt1
= t1
& VT_BTYPE
;
3385 bt2
= t2
& VT_BTYPE
;
3387 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3388 /* at least one operand is a pointer */
3389 /* relationnal op: must be both pointers */
3390 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3391 // check_pointer_types(vtop, vtop - 1);
3392 /* pointers are handled are unsigned */
3393 t
= VT_INT
| VT_UNSIGNED
;
3396 /* if both pointers, then it must be the '-' op */
3397 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3398 (t2
& VT_BTYPE
) == VT_PTR
) {
3400 error("cannot use pointers here");
3401 // check_pointer_types(vtop - 1, vtop);
3402 /* XXX: check that types are compatible */
3403 u
= pointed_size(t1
);
3405 /* set to integer type */
3410 /* exactly one pointer : must be '+' or '-'. */
3411 if (op
!= '-' && op
!= '+')
3412 error("cannot use pointers here");
3413 /* Put pointer as first operand */
3414 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3418 /* XXX: cast to int ? (long long case) */
3419 vpushi(pointed_size(vtop
[-1].t
));
3421 #ifdef CONFIG_TCC_BCHECK
3422 /* if evaluating constant expression, no code should be
3423 generated, so no bound check */
3424 if (do_bounds_check
&& !const_wanted
) {
3425 /* if bounded pointers, we generate a special code to
3432 gen_bounded_ptr_add();
3438 /* put again type if gen_opic() swaped operands */
3441 } else if (is_float(bt1
) || is_float(bt2
)) {
3442 /* compute bigger type and do implicit casts */
3443 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3445 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3450 /* floats can only be used for a few operations */
3451 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3452 (op
< TOK_ULT
|| op
> TOK_GT
))
3453 error("invalid operands for binary operation");
3455 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3456 /* cast to biggest op */
3458 /* convert to unsigned if it does not fit in a long long */
3459 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3460 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3464 /* integer operations */
3466 /* convert to unsigned if it does not fit in an integer */
3467 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3468 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3471 /* XXX: currently, some unsigned operations are explicit, so
3472 we modify them here */
3473 if (t
& VT_UNSIGNED
) {
3480 else if (op
== TOK_LT
)
3482 else if (op
== TOK_GT
)
3484 else if (op
== TOK_LE
)
3486 else if (op
== TOK_GE
)
3492 /* special case for shifts and long long: we keep the shift as
3494 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3500 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3504 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3505 /* relationnal op: the result is an int */
3513 /* generic itof for unsigned long long case */
3514 void gen_cvt_itof1(int t
)
3518 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3519 (VT_LLONG
| VT_UNSIGNED
)) {
3521 gfunc_start(&gf
, FUNC_CDECL
);
3524 vpushi((int)&__ulltof
);
3525 else if (t
== VT_DOUBLE
)
3526 vpushi((int)&__ulltod
);
3528 vpushi((int)&__ulltold
);
3537 /* generic ftoi for unsigned long long case */
3538 void gen_cvt_ftoi1(int t
)
3543 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3544 /* not handled natively */
3545 gfunc_start(&gf
, FUNC_CDECL
);
3546 st
= vtop
->t
& VT_BTYPE
;
3549 vpushi((int)&__ftoull
);
3550 else if (st
== VT_DOUBLE
)
3551 vpushi((int)&__dtoull
);
3553 vpushi((int)&__ldtoull
);
3557 vtop
->r2
= REG_LRET
;
3563 /* force char or short cast */
3564 void force_charshort_cast(int t
)
3568 /* XXX: add optimization if lvalue : just change type and offset */
3573 if (t
& VT_UNSIGNED
) {
3574 vpushi((1 << bits
) - 1);
3585 /* cast 'vtop' to 't' type */
3586 void gen_cast(int t
)
3588 int sbt
, dbt
, sf
, df
, c
;
3590 /* special delayed cast for char/short */
3591 /* XXX: in some cases (multiple cascaded casts), it may still
3593 if (vtop
->r
& VT_MUSTCAST
) {
3594 vtop
->r
&= ~VT_MUSTCAST
;
3595 force_charshort_cast(vtop
->t
);
3598 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3599 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3604 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3606 /* convert from fp to fp */
3608 /* constant case: we can do it now */
3609 /* XXX: in ISOC, cannot do it if error in convert */
3610 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3611 vtop
->c
.f
= (float)vtop
->c
.d
;
3612 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3613 vtop
->c
.f
= (float)vtop
->c
.ld
;
3614 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3615 vtop
->c
.d
= (double)vtop
->c
.f
;
3616 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3617 vtop
->c
.d
= (double)vtop
->c
.ld
;
3618 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3619 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3620 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3621 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3623 /* non constant case: generate code */
3627 /* convert int to fp */
3630 case VT_LLONG
| VT_UNSIGNED
:
3632 /* XXX: add const cases for long long */
3634 case VT_INT
| VT_UNSIGNED
:
3636 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3637 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3638 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3643 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3644 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3645 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3654 /* convert fp to int */
3655 /* we handle char/short/etc... with generic code */
3656 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3657 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3662 case VT_LLONG
| VT_UNSIGNED
:
3664 /* XXX: add const cases for long long */
3666 case VT_INT
| VT_UNSIGNED
:
3668 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3669 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3670 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3676 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3677 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3678 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3686 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3687 /* additionnal cast for char/short/bool... */
3691 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3692 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3693 /* scalar to long long */
3695 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3696 vtop
->c
.ll
= vtop
->c
.ui
;
3698 vtop
->c
.ll
= vtop
->c
.i
;
3700 /* machine independant conversion */
3702 /* generate high word */
3703 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3711 /* patch second register */
3712 vtop
[-1].r2
= vtop
->r
;
3716 } else if (dbt
== VT_BOOL
) {
3717 /* scalar to bool */
3720 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3721 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3722 force_charshort_cast(t
);
3723 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3725 if (sbt
== VT_LLONG
) {
3726 /* from long long: just take low order word */
3730 /* if lvalue and single word type, nothing to do because
3731 the lvalue already contains the real type size (see
3732 VT_LVAL_xxx constants) */
3738 /* return type size. Put alignment at 'a' */
3739 int type_size(int t
, int *a
)
3745 if (bt
== VT_STRUCT
) {
3747 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3748 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3750 } else if (bt
== VT_PTR
) {
3752 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3753 return type_size(s
->t
, a
) * s
->c
;
3758 } else if (bt
== VT_LDOUBLE
) {
3760 return LDOUBLE_SIZE
;
3761 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3764 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3767 } else if (bt
== VT_SHORT
) {
3771 /* char, void, function, _Bool */
3777 /* return the pointed type of t */
3778 int pointed_type(int t
)
3781 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3782 return s
->t
| (t
& ~VT_TYPE
);
3785 int mk_pointer(int t
)
3789 sym_push(p
, t
, 0, -1);
3790 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3793 int is_compatible_types(int t1
, int t2
)
3800 bt1
= t1
& VT_BTYPE
;
3801 bt2
= t2
& VT_BTYPE
;
3802 if (bt1
== VT_PTR
) {
3803 t1
= pointed_type(t1
);
3804 /* if function, then convert implicitely to function pointer */
3805 if (bt2
!= VT_FUNC
) {
3808 t2
= pointed_type(t2
);
3810 /* void matches everything */
3813 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3815 return is_compatible_types(t1
, t2
);
3816 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3818 } else if (bt1
== VT_FUNC
) {
3821 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3822 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3823 if (!is_compatible_types(s1
->t
, s2
->t
))
3825 /* XXX: not complete */
3826 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3830 while (s1
!= NULL
) {
3833 if (!is_compatible_types(s1
->t
, s2
->t
))
3842 /* XXX: not complete */
3847 /* print a type. If 'varstr' is not NULL, then the variable is also
3848 printed in the type */
3850 /* XXX: add array and function pointers */
3851 void type_to_str(char *buf
, int buf_size
,
3852 int t
, const char *varstr
)
3862 if (t
& VT_UNSIGNED
)
3863 pstrcat(buf
, buf_size
, "unsigned ");
3893 tstr
= "long double";
3895 pstrcat(buf
, buf_size
, tstr
);
3899 if (bt
== VT_STRUCT
)
3903 pstrcat(buf
, buf_size
, tstr
);
3904 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3905 if (v
>= SYM_FIRST_ANOM
)
3906 pstrcat(buf
, buf_size
, "<anonymous>");
3908 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3911 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3912 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3913 pstrcat(buf
, buf_size
, "(");
3915 while (sa
!= NULL
) {
3916 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3917 pstrcat(buf
, buf_size
, buf1
);
3920 pstrcat(buf
, buf_size
, ", ");
3922 pstrcat(buf
, buf_size
, ")");
3925 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3926 pstrcpy(buf1
, sizeof(buf1
), "*");
3928 pstrcat(buf1
, sizeof(buf1
), varstr
);
3929 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3933 pstrcat(buf
, buf_size
, " ");
3934 pstrcat(buf
, buf_size
, varstr
);
3939 /* verify type compatibility to store vtop in 'dt' type, and generate
3941 void gen_assign_cast(int dt
)
3944 char buf1
[256], buf2
[256];
3946 st
= vtop
->t
; /* source type */
3947 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3948 /* special cases for pointers */
3949 /* a function is implicitely a function pointer */
3950 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3951 if (!is_compatible_types(pointed_type(dt
), st
))
3956 /* '0' can also be a pointer */
3957 if ((st
& VT_BTYPE
) == VT_INT
&&
3958 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3962 if (!is_compatible_types(dt
, st
)) {
3964 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3965 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3966 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3972 /* store vtop in lvalue pushed on stack */
3975 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3979 sbt
= vtop
->t
& VT_BTYPE
;
3980 dbt
= ft
& VT_BTYPE
;
3981 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3982 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3983 /* optimize char/short casts */
3984 delayed_cast
= VT_MUSTCAST
;
3985 vtop
->t
= ft
& VT_TYPE
;
3988 gen_assign_cast(ft
& VT_TYPE
);
3991 if (sbt
== VT_STRUCT
) {
3992 /* if structure, only generate pointer */
3993 /* structure assignment : generate memcpy */
3994 /* XXX: optimize if small size */
3996 gfunc_start(&gf
, FUNC_CDECL
);
3998 size
= type_size(vtop
->t
, &align
);
4012 vpushi((int)&memcpy
);
4014 /* leave source on stack */
4015 } else if (ft
& VT_BITFIELD
) {
4016 /* bitfield store handling */
4017 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4018 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4019 /* remove bit field info to avoid loops */
4020 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4022 /* duplicate destination */
4024 vtop
[-1] = vtop
[-2];
4026 /* mask and shift source */
4027 vpushi((1 << bit_size
) - 1);
4031 /* load destination, mask and or with source */
4033 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4039 #ifdef CONFIG_TCC_BCHECK
4040 /* bound check case */
4041 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4050 r
= gv(rc
); /* generate value */
4051 /* if lvalue was saved on stack, must read it */
4052 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4054 t
= get_reg(RC_INT
);
4056 sv
.r
= VT_LOCAL
| VT_LVAL
;
4057 sv
.c
.ul
= vtop
[-1].c
.ul
;
4059 vtop
[-1].r
= t
| VT_LVAL
;
4062 /* two word case handling : store second register at word + 4 */
4063 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4065 /* convert to int to increment easily */
4072 /* XXX: it works because r2 is spilled last ! */
4073 store(vtop
->r2
, vtop
- 1);
4076 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4077 vtop
->r
|= delayed_cast
;
4081 /* post defines POST/PRE add. c is the token ++ or -- */
4082 void inc(int post
, int c
)
4085 vdup(); /* save lvalue */
4087 gv_dup(); /* duplicate value */
4092 vpushi(c
- TOK_MID
);
4094 vstore(); /* store value */
4096 vpop(); /* if post op, return saved value */
4099 /* Parse GNUC __attribute__ extension. Currently, the following
4100 extensions are recognized:
4101 - aligned(n) : set data/function alignment.
4102 - section(x) : generate data/code in this section.
4103 - unused : currently ignored, but may be used someday.
4105 void parse_attribute(AttributeDef
*ad
)
4112 while (tok
!= ')') {
4113 if (tok
< TOK_IDENT
)
4114 expect("attribute name");
4119 case TOK___SECTION__
:
4122 expect("section name");
4123 ad
->section
= find_section(tokc
.ts
->str
);
4128 case TOK___ALIGNED__
:
4131 if (n
<= 0 || (n
& (n
- 1)) != 0)
4132 error("alignment must be a positive power of two");
4137 case TOK___UNUSED__
:
4138 /* currently, no need to handle it because tcc does not
4139 track unused objects */
4142 case TOK___NORETURN__
:
4143 /* currently, no need to handle it because tcc does not
4144 track unused objects */
4149 ad
->func_call
= FUNC_CDECL
;
4153 case TOK___STDCALL__
:
4154 ad
->func_call
= FUNC_STDCALL
;
4157 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4158 /* skip parameters */
4159 /* XXX: skip parenthesis too */
4162 while (tok
!= ')' && tok
!= -1)
4176 /* enum/struct/union declaration */
4177 int struct_decl(int u
)
4179 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4180 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4184 a
= tok
; /* save decl type */
4189 /* struct already defined ? return it */
4190 /* XXX: check consistency */
4191 s
= sym_find(v
| SYM_STRUCT
);
4194 error("invalid type");
4200 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4201 /* put struct/union/enum name in type */
4203 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4208 error("struct/union/enum already defined");
4209 /* cannot be empty */
4216 if (a
== TOK_ENUM
) {
4223 /* enum symbols have static storage */
4224 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4229 parse_btype(&b
, &ad
);
4234 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4235 if ((t
& VT_BTYPE
) == VT_FUNC
||
4236 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4237 error("invalid type for '%s'",
4238 get_tok_str(v
, NULL
));
4244 bit_size
= expr_const();
4245 /* XXX: handle v = 0 case for messages */
4247 error("negative width in bit-field '%s'",
4248 get_tok_str(v
, NULL
));
4249 if (v
&& bit_size
== 0)
4250 error("zero width for bit-field '%s'",
4251 get_tok_str(v
, NULL
));
4253 size
= type_size(t
, &align
);
4255 if (bit_size
>= 0) {
4260 error("bitfields must have scalar type");
4262 if (bit_size
> bsize
) {
4263 error("width of '%s' exceeds its type",
4264 get_tok_str(v
, NULL
));
4265 } else if (bit_size
== bsize
) {
4266 /* no need for bit fields */
4268 } else if (bit_size
== 0) {
4269 /* XXX: what to do if only padding in a
4271 /* zero size: means to pad */
4275 /* we do not have enough room ? */
4276 if ((bit_pos
+ bit_size
) > bsize
)
4279 /* XXX: handle LSB first */
4281 (bit_pos
<< VT_STRUCT_SHIFT
) |
4282 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4283 bit_pos
+= bit_size
;
4289 /* add new memory data only if starting
4291 if (lbit_pos
== 0) {
4292 if (a
== TOK_STRUCT
) {
4293 c
= (c
+ align
- 1) & -align
;
4301 if (align
> maxalign
)
4305 printf("add field %s offset=%d",
4306 get_tok_str(v
, NULL
), offset
);
4307 if (t
& VT_BITFIELD
) {
4308 printf(" pos=%d size=%d",
4309 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4310 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4314 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4318 if (tok
== ';' || tok
== -1)
4328 /* size for struct/union, dummy for enum */
4329 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4334 /* return 0 if no type declaration. otherwise, return the basic type
4337 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4339 int t
, u
, type_found
;
4342 memset(ad
, 0, sizeof(AttributeDef
));
4353 if ((t
& VT_BTYPE
) != 0)
4354 error("too many basic types");
4368 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4369 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4370 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4371 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4385 if ((t
& VT_BTYPE
) == VT_LONG
) {
4386 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4393 u
= struct_decl(VT_ENUM
);
4397 u
= struct_decl(VT_STRUCT
);
4400 /* type modifiers */
4405 case TOK___SIGNED__
:
4408 case TOK___INLINE__
:
4430 /* GNUC attribute */
4431 case TOK___ATTRIBUTE__
:
4432 parse_attribute(ad
);
4436 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4438 t
|= (s
->t
& ~VT_TYPEDEF
);
4445 /* long is never used as type */
4446 if ((t
& VT_BTYPE
) == VT_LONG
)
4447 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4452 int post_type(int t
, AttributeDef
*ad
)
4454 int p
, n
, pt
, l
, t1
;
4455 Sym
**plast
, *s
, *first
;
4459 /* function declaration */
4464 while (tok
!= ')') {
4465 /* read param name and compute offset */
4466 if (l
!= FUNC_OLD
) {
4467 if (!parse_btype(&pt
, &ad1
)) {
4469 error("invalid type");
4476 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4478 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4479 if ((pt
& VT_BTYPE
) == VT_VOID
)
4480 error("parameter declared as void");
4487 /* array must be transformed to pointer according to ANSI C */
4489 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4494 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4501 /* if no parameters, then old type prototype */
4505 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4506 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4507 /* we push a anonymous symbol which will contain the function prototype */
4509 s
= sym_push(p
, t
, ad
->func_call
, l
);
4511 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4512 } else if (tok
== '[') {
4513 /* array definition */
4519 error("invalid array size");
4522 /* parse next post type */
4523 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4524 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4526 /* we push a anonymous symbol which will contain the array
4529 sym_push(p
, t
, 0, n
);
4530 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4535 /* Read a type declaration (except basic type), and return the
4536 type. 'td' is a bitmask indicating which kind of type decl is
4537 expected. 't' should contain the basic type. 'ad' is the attribute
4538 definition of the basic type. It can be modified by type_decl(). */
4539 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4544 while (tok
== '*') {
4546 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4551 /* recursive type */
4552 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4555 /* XXX: this is not correct to modify 'ad' at this point, but
4556 the syntax is not clear */
4557 if (tok
== TOK___ATTRIBUTE__
)
4558 parse_attribute(ad
);
4559 u
= type_decl(ad
, v
, 0, td
);
4563 /* type identifier */
4564 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4568 if (!(td
& TYPE_ABSTRACT
))
4569 expect("identifier");
4573 /* append t at the end of u */
4574 t
= post_type(t
, ad
);
4575 if (tok
== TOK___ATTRIBUTE__
)
4576 parse_attribute(ad
);
4581 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4591 /* define a new external reference to a symbol 'v' of type 'u' */
4592 Sym
*external_sym(int v
, int u
, int r
)
4598 /* push forward reference */
4599 s
= sym_push1(&global_stack
,
4600 v
, u
| VT_EXTERN
, 0);
4601 s
->r
= r
| VT_CONST
| VT_SYM
;
4606 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4607 static int lvalue_type(int t
)
4614 else if (bt
== VT_SHORT
)
4618 if (t
& VT_UNSIGNED
)
4619 r
|= VT_LVAL_UNSIGNED
;
4623 /* indirection with full error checking and bound check */
4624 static void indir(void)
4626 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4628 if (vtop
->r
& VT_LVAL
)
4630 vtop
->t
= pointed_type(vtop
->t
);
4631 /* an array is never an lvalue */
4632 if (!(vtop
->t
& VT_ARRAY
)) {
4633 vtop
->r
|= lvalue_type(vtop
->t
);
4634 /* if bound checking, the referenced pointer must be checked */
4635 if (do_bounds_check
)
4636 vtop
->r
|= VT_MUSTBOUND
;
4640 /* pass a parameter to a function and do type checking and casting */
4641 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4644 func_type
= func
->c
;
4645 if (func_type
== FUNC_OLD
||
4646 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4647 /* default casting : only need to convert float to double */
4648 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4649 gen_cast(VT_DOUBLE
);
4650 } else if (arg
== NULL
) {
4651 error("too many arguments to function");
4653 gen_assign_cast(arg
->t
);
4660 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
4665 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4668 } else if (tok
== TOK_CUINT
) {
4669 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4671 } else if (tok
== TOK_CLLONG
) {
4672 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4674 } else if (tok
== TOK_CULLONG
) {
4675 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4677 } else if (tok
== TOK_CFLOAT
) {
4678 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4680 } else if (tok
== TOK_CDOUBLE
) {
4681 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4683 } else if (tok
== TOK_CLDOUBLE
) {
4684 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4686 } else if (tok
== TOK___FUNC__
) {
4687 /* special function name identifier */
4688 /* generate (char *) type */
4689 data_offset
= data_section
->data_ptr
- data_section
->data
;
4690 vpush_ref(mk_pointer(VT_BYTE
), data_section
, data_offset
);
4691 strcpy(data_section
->data
+ data_offset
, funcname
);
4692 data_offset
+= strlen(funcname
) + 1;
4693 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4695 } else if (tok
== TOK_LSTR
) {
4698 } else if (tok
== TOK_STR
) {
4699 /* string parsing */
4702 type_size(t
, &align
);
4703 data_offset
= data_section
->data_ptr
- data_section
->data
;
4704 data_offset
= (data_offset
+ align
- 1) & -align
;
4706 /* we must declare it as an array first to use initializer parser */
4707 t
= VT_ARRAY
| mk_pointer(t
);
4708 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4709 data_offset
+= type_size(t
, &align
);
4710 /* put it as pointer */
4711 vpush_ref(t
& ~VT_ARRAY
, data_section
, fc
);
4712 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4718 if (parse_btype(&t
, &ad
)) {
4719 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4721 /* check ISOC99 compound literal */
4723 /* data is allocated locally by default */
4728 /* all except arrays are lvalues */
4729 if (!(ft
& VT_ARRAY
))
4730 r
|= lvalue_type(ft
);
4731 memset(&ad
, 0, sizeof(AttributeDef
));
4732 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4741 } else if (t
== '*') {
4744 } else if (t
== '&') {
4746 /* functions names must be treated as function pointers,
4747 except for unary '&' and sizeof. Since we consider that
4748 functions are not lvalues, we only have to handle it
4749 there and in function calls. */
4750 /* arrays can also be used although they are not lvalues */
4751 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4752 !(vtop
->t
& VT_ARRAY
))
4754 vtop
->t
= mk_pointer(vtop
->t
);
4759 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4760 vtop
->c
.i
= !vtop
->c
.i
;
4761 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4762 vtop
->c
.i
= vtop
->c
.i
^ 1;
4764 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4774 if (t
== TOK_SIZEOF
) {
4777 if (parse_btype(&t
, &ad
)) {
4778 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4780 /* XXX: some code could be generated: add eval
4792 vpushi(type_size(t
, &t
));
4794 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4797 } else if (t
== '-') {
4804 expect("identifier");
4808 error("'%s' undeclared", get_tok_str(t
, NULL
));
4809 /* for simple function calls, we tolerate undeclared
4810 external reference */
4812 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4813 /* int() function */
4814 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4816 vset(s
->t
, s
->r
, s
->c
);
4817 /* if forward reference, we must point to s */
4818 if (vtop
->r
& VT_SYM
)
4823 /* post operations */
4825 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4828 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4830 if (tok
== TOK_ARROW
)
4835 /* expect pointer on structure */
4836 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4837 expect("struct or union");
4838 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4841 while ((s
= s
->next
) != NULL
) {
4846 error("field not found");
4847 /* add field offset to pointer */
4848 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4851 /* change type to field type, and set to lvalue */
4853 /* an array is never an lvalue */
4854 if (!(vtop
->t
& VT_ARRAY
))
4855 vtop
->r
|= lvalue_type(vtop
->t
);
4857 } else if (tok
== '[') {
4863 } else if (tok
== '(') {
4868 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4869 /* pointer test (no array accepted) */
4870 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4871 vtop
->t
= pointed_type(vtop
->t
);
4872 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4876 expect("function pointer");
4879 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4881 /* get return type */
4882 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4883 save_regs(0); /* save used temporary registers */
4884 gfunc_start(&gf
, s
->r
);
4886 sa
= s
->next
; /* first parameter */
4887 #ifdef INVERT_FUNC_PARAMS
4891 ParseState saved_parse_state
;
4894 /* read each argument and store it on a stack */
4895 /* XXX: merge it with macro args ? */
4901 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4905 else if (tok
== ')')
4907 tok_str_add_tok(&str
);
4910 tok_str_add(&str
, -1); /* end of file added */
4911 tok_str_add(&str
, 0);
4912 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4913 s1
->next
= sa
; /* add reference to argument */
4922 /* now generate code in reverse order by reading the stack */
4923 save_parse_state(&saved_parse_state
);
4925 macro_ptr
= (int *)args
->c
;
4929 expect("',' or ')'");
4930 gfunc_param_typed(&gf
, s
, args
->next
);
4932 free((int *)args
->c
);
4936 restore_parse_state(&saved_parse_state
);
4939 /* compute first implicit argument if a structure is returned */
4940 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4941 /* get some space for the returned structure */
4942 size
= type_size(s
->t
, &align
);
4943 loc
= (loc
- size
) & -align
;
4945 ret
.r
= VT_LOCAL
| VT_LVAL
;
4946 /* pass it as 'int' to avoid structure arg passing
4948 vset(VT_INT
, VT_LOCAL
, loc
);
4954 /* return in register */
4955 if (is_float(ret
.t
)) {
4958 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4964 #ifndef INVERT_FUNC_PARAMS
4968 gfunc_param_typed(&gf
, s
, sa
);
4978 error("too few arguments to function");
4982 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4996 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4997 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4998 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5021 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5022 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5023 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5024 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5025 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5026 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5027 (l
== 5 && tok
== '&') ||
5028 (l
== 6 && tok
== '^') ||
5029 (l
== 7 && tok
== '|') ||
5030 (l
== 8 && tok
== TOK_LAND
) ||
5031 (l
== 9 && tok
== TOK_LOR
)) {
5040 /* only used if non constant */
5048 if (tok
!= TOK_LAND
) {
5051 vset(VT_INT
, VT_JMPI
, t
);
5068 if (tok
!= TOK_LOR
) {
5071 vset(VT_INT
, VT_JMP
, t
);
5081 /* XXX: better constant handling */
5084 int t
, u
, c
, r1
, r2
, rc
;
5104 save_regs(1); /* we need to save all registers here except
5105 at the top because it is a branch point */
5108 /* XXX: long long handling ? */
5110 if (is_float(vtop
->t
))
5113 vtop
--; /* no vpop so that FP stack is not flushed */
5138 /* parse a constant expression and return value in vtop */
5139 void expr_const1(void)
5145 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5150 /* parse an integer constant and return its value */
5151 int expr_const(void)
5160 /* return the label token if current token is a label, otherwise
5167 /* fast test first */
5168 if (tok
< TOK_UIDENT
)
5170 /* no need to save tokc since we expect an identifier */
5178 /* XXX: may not work in all cases (macros ?) */
5187 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5192 /* generate line number info */
5194 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5195 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5197 last_line_num
= file
->line_num
;
5200 if (tok
== TOK_IF
) {
5207 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5209 if (c
== TOK_ELSE
) {
5213 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5214 gsym(d
); /* patch else jmp */
5217 } else if (tok
== TOK_WHILE
) {
5225 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5229 } else if (tok
== '{') {
5232 s
= local_stack
.top
;
5233 while (tok
!= '}') {
5236 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5238 /* pop locally defined symbols */
5239 sym_pop(&local_stack
, s
);
5241 } else if (tok
== TOK_RETURN
) {
5245 gen_assign_cast(func_vt
);
5246 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5247 /* if returning structure, must copy it to implicit
5248 first pointer arg location */
5249 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5252 /* copy structure value to pointer */
5254 } else if (is_float(func_vt
)) {
5259 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5262 rsym
= gjmp(rsym
); /* jmp */
5263 } else if (tok
== TOK_BREAK
) {
5266 error("cannot break");
5267 *bsym
= gjmp(*bsym
);
5270 } else if (tok
== TOK_CONTINUE
) {
5273 error("cannot continue");
5274 *csym
= gjmp(*csym
);
5277 } else if (tok
== TOK_FOR
) {
5304 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5309 if (tok
== TOK_DO
) {
5314 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5325 if (tok
== TOK_SWITCH
) {
5329 /* XXX: other types than integer */
5330 case_reg
= gv(RC_INT
);
5334 b
= gjmp(0); /* jump to first case */
5336 block(&a
, csym
, &b
, &c
, case_reg
);
5337 /* if no default, jmp after switch */
5345 if (tok
== TOK_CASE
) {
5352 if (gnu_ext
&& tok
== TOK_DOTS
) {
5356 warning("empty case range");
5358 /* since a case is like a label, we must skip it with a jmp */
5361 vset(VT_INT
, case_reg
, 0);
5365 *case_sym
= gtst(1, 0);
5368 *case_sym
= gtst(1, 0);
5369 vset(VT_INT
, case_reg
, 0);
5372 *case_sym
= gtst(1, *case_sym
);
5376 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5378 if (tok
== TOK_DEFAULT
) {
5384 error("too many 'default'");
5386 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5388 if (tok
== TOK_GOTO
) {
5390 s
= sym_find1(&label_stack
, tok
);
5391 /* put forward definition if needed */
5393 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5394 /* label already defined */
5395 if (s
->t
& LABEL_FORWARD
)
5405 s
= sym_find1(&label_stack
, b
);
5407 if (!(s
->t
& LABEL_FORWARD
))
5408 error("multiple defined label");
5413 sym_push1(&label_stack
, b
, 0, ind
);
5415 /* we accept this, but it is a mistake */
5417 warning("deprecated use of label at end of compound statement");
5419 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5421 /* expression case */
5431 /* t is the array or struct type. c is the array or struct
5432 address. cur_index/cur_field is the pointer to the current
5433 value. 'size_only' is true if only size info is needed (only used
5435 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5436 int *cur_index
, Sym
**cur_field
,
5440 int notfirst
, index
, align
, l
;
5443 if (gnu_ext
&& (l
= is_label()) != 0)
5446 while (tok
== '[' || tok
== '.') {
5448 if (!(t
& VT_ARRAY
))
5449 expect("array type");
5450 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5452 index
= expr_const();
5453 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5454 expect("invalid index");
5458 t
= pointed_type(t
);
5459 c
+= index
* type_size(t
, &align
);
5465 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5466 expect("struct/union type");
5467 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5479 t
= f
->t
| (t
& ~VT_TYPE
);
5494 t
= pointed_type(t
);
5495 c
+= index
* type_size(t
, &align
);
5499 error("too many field init");
5500 t
= f
->t
| (t
& ~VT_TYPE
);
5504 decl_initializer(t
, sec
, c
, 0, size_only
);
5508 #define EXPR_CONST 1
5511 /* store a value or an expression directly in global data or in local array */
5512 void init_putv(int t
, Section
*sec
, unsigned long c
,
5513 int v
, int expr_type
)
5515 int saved_global_expr
, bt
;
5523 /* compound literals must be allocated globally in this case */
5524 saved_global_expr
= global_expr
;
5527 global_expr
= saved_global_expr
;
5535 /* XXX: not portable */
5536 /* XXX: generate error if incorrect relocation */
5539 ptr
= sec
->data
+ c
;
5540 if ((vtop
->r
& VT_SYM
) &&
5546 error("initializer element is not computable at load time");
5549 *(char *)ptr
= vtop
->c
.i
;
5552 *(short *)ptr
= vtop
->c
.i
;
5555 *(double *)ptr
= vtop
->c
.d
;
5558 *(long double *)ptr
= vtop
->c
.ld
;
5561 *(long long *)ptr
= vtop
->c
.ll
;
5564 if (vtop
->r
& VT_SYM
) {
5565 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5568 *(int *)ptr
= vtop
->c
.i
;
5574 vset(t
, VT_LOCAL
, c
);
5581 /* put zeros for variable based init */
5582 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5587 /* nothing to do because globals are already set to zero */
5589 gfunc_start(&gf
, FUNC_CDECL
);
5594 vset(VT_INT
, VT_LOCAL
, c
);
5596 vpushi((int)&memset
);
5601 /* 't' contains the type and storage info. 'c' is the offset of the
5602 object in section 'sec'. If 'sec' is NULL, it means stack based
5603 allocation. 'first' is true if array '{' must be read (multi
5604 dimension implicit array init handling). 'size_only' is true if
5605 size only evaluation is wanted (only for arrays). */
5606 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5608 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5609 int t1
, size1
, align1
, expr_type
;
5614 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5617 t1
= pointed_type(t
);
5618 size1
= type_size(t1
, &align1
);
5621 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5627 /* only parse strings here if correct type (otherwise: handle
5628 them as ((w)char *) expressions */
5629 if ((tok
== TOK_LSTR
&&
5630 (t1
& VT_BTYPE
) == VT_INT
) ||
5632 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5633 /* XXX: move multiple string parsing in parser ? */
5634 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5636 /* compute maximum number of chars wanted */
5638 if (n
>= 0 && nb
> (n
- array_length
))
5639 nb
= n
- array_length
;
5642 warning("initializer-string for array is too long");
5644 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5645 ts
->str
[i
], EXPR_VAL
);
5651 /* only add trailing zero if enough storage (no
5652 warning in this case since it is standard) */
5653 if (n
< 0 || array_length
< n
) {
5655 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5661 while (tok
!= '}') {
5662 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5663 if (n
>= 0 && index
>= n
)
5664 error("index too large");
5665 /* must put zero in holes (note that doing it that way
5666 ensures that it even works with designators) */
5667 if (!size_only
&& array_length
< index
) {
5668 init_putz(t1
, sec
, c
+ array_length
* size1
,
5669 (index
- array_length
) * size1
);
5672 if (index
> array_length
)
5673 array_length
= index
;
5674 /* special test for multi dimensional arrays (may not
5675 be strictly correct if designators are used at the
5677 if (index
>= n
&& no_oblock
)
5686 /* put zeros at the end */
5687 if (!size_only
&& n
>= 0 && array_length
< n
) {
5688 init_putz(t1
, sec
, c
+ array_length
* size1
,
5689 (n
- array_length
) * size1
);
5691 /* patch type size if needed */
5693 s
->c
= array_length
;
5694 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5695 /* XXX: union needs only one init */
5697 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5702 while (tok
!= '}') {
5703 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5704 /* fill with zero between fields */
5706 if (!size_only
&& array_length
< index
) {
5707 init_putz(t
, sec
, c
+ array_length
,
5708 index
- array_length
);
5710 index
= index
+ type_size(f
->t
, &align1
);
5711 if (index
> array_length
)
5712 array_length
= index
;
5718 /* put zeros at the end */
5719 if (!size_only
&& array_length
< n
) {
5720 init_putz(t
, sec
, c
+ array_length
,
5724 } else if (tok
== '{') {
5726 decl_initializer(t
, sec
, c
, first
, size_only
);
5728 } else if (size_only
) {
5729 /* just skip expression */
5731 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5735 else if (tok
== ')')
5740 /* currently, we always use constant expression for globals
5741 (may change for scripting case) */
5742 expr_type
= EXPR_CONST
;
5744 expr_type
= EXPR_ANY
;
5745 init_putv(t
, sec
, c
, 0, expr_type
);
5749 /* parse an initializer for type 't' if 'has_init' is true, and
5750 allocate space in local or global data space ('r' is either
5751 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5752 variable 'v' of scope 'scope' is declared before initializers are
5753 parsed. If 'v' is zero, then a reference to the new object is put
5754 in the value stack. */
5755 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5758 int size
, align
, addr
, data_offset
;
5760 ParseState saved_parse_state
;
5761 TokenString init_str
;
5764 size
= type_size(t
, &align
);
5765 /* If unknown size, we must evaluate it before
5766 evaluating initializers because
5767 initializers can generate global data too
5768 (e.g. string pointers or ISOC99 compound
5769 literals). It also simplifies local
5770 initializers handling */
5771 tok_str_new(&init_str
);
5774 error("unknown type size");
5775 /* get all init string */
5777 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5779 error("unexpected end of file in initializer");
5780 tok_str_add_tok(&init_str
);
5783 else if (tok
== '}') {
5790 tok_str_add(&init_str
, -1);
5791 tok_str_add(&init_str
, 0);
5794 save_parse_state(&saved_parse_state
);
5796 macro_ptr
= init_str
.str
;
5798 decl_initializer(t
, NULL
, 0, 1, 1);
5799 /* prepare second initializer parsing */
5800 macro_ptr
= init_str
.str
;
5803 /* if still unknown size, error */
5804 size
= type_size(t
, &align
);
5806 error("unknown type size");
5808 /* take into account specified alignment if bigger */
5809 if (ad
->aligned
> align
)
5810 align
= ad
->aligned
;
5811 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5813 if (do_bounds_check
&& (t
& VT_ARRAY
))
5815 #ifdef TCC_TARGET_IL
5816 /* XXX: ugly patch to allocate local variables for IL, just
5821 loc
= (loc
- size
) & -align
;
5824 /* handles bounds */
5825 /* XXX: currently, since we do only one pass, we cannot track
5826 '&' operators, so we add only arrays */
5827 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5829 /* add padding between regions */
5831 /* then add local bound info */
5832 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5833 *bounds_ptr
++ = addr
;
5834 *bounds_ptr
++ = size
;
5835 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5838 /* compute section */
5846 data_offset
= sec
->data_ptr
- sec
->data
;
5847 data_offset
= (data_offset
+ align
- 1) & -align
;
5849 /* very important to increment global pointer at this time
5850 because initializers themselves can create new initializers */
5851 data_offset
+= size
;
5852 /* handles bounds */
5853 if (do_bounds_check
) {
5855 /* first, we need to add at least one byte between each region */
5857 /* then add global bound info */
5858 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5859 /* XXX: add relocation */
5860 *bounds_ptr
++ = addr
+ (unsigned long)sec
->data
;
5861 *bounds_ptr
++ = size
;
5862 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5864 sec
->data_ptr
= sec
->data
+ data_offset
;
5870 /* local variable */
5871 sym_push(v
, t
, r
, addr
);
5873 if (scope
== VT_CONST
) {
5874 /* global scope: see if already defined */
5878 if (!is_compatible_types(sym
->t
, t
))
5879 error("incompatible types for redefinition of '%s'",
5880 get_tok_str(v
, NULL
));
5881 if (!(sym
->t
& VT_EXTERN
))
5882 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5883 sym
->t
&= ~VT_EXTERN
;
5886 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5888 put_extern_sym(sym
, sec
, addr
);
5892 /* push local reference */
5895 /* push global reference */
5896 vpush_ref(t
, sec
, addr
);
5900 decl_initializer(t
, sec
, addr
, 1, 0);
5901 /* restore parse state if needed */
5904 restore_parse_state(&saved_parse_state
);
5909 void put_func_debug(int t
)
5914 /* XXX: we put here a dummy type */
5915 snprintf(buf
, sizeof(buf
), "%s:%c1",
5916 funcname
, t
& VT_STATIC
? 'f' : 'F');
5917 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5923 /* not finished : try to put some local vars in registers */
5924 //#define CONFIG_REG_VARS
5926 #ifdef CONFIG_REG_VARS
5927 void add_var_ref(int t
)
5929 printf("%s:%d: &%s\n",
5930 file
->filename
, file
->line_num
,
5931 get_tok_str(t
, NULL
));
5934 /* first pass on a function with heuristic to extract variable usage
5935 and pointer references to local variables for register allocation */
5936 void analyse_function(void)
5943 /* any symbol coming after '&' is considered as being a
5944 variable whose reference is taken. It is highly unaccurate
5945 but it is difficult to do better without a complete parse */
5948 /* if '& number', then no need to examine next tokens */
5949 if (tok
== TOK_CINT
||
5951 tok
== TOK_CLLONG
||
5952 tok
== TOK_CULLONG
) {
5954 } else if (tok
>= TOK_UIDENT
) {
5955 /* if '& ident [' or '& ident ->', then ident address
5959 if (tok
!= '[' && tok
!= TOK_ARROW
)
5963 while (tok
!= '}' && tok
!= ';' &&
5964 !((tok
== ',' || tok
== ')') && level
== 0)) {
5965 if (tok
>= TOK_UIDENT
) {
5967 } else if (tok
== '(') {
5969 } else if (tok
== ')') {
5982 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5985 int t
, b
, v
, has_init
, r
;
5990 if (!parse_btype(&b
, &ad
)) {
5991 /* skip redundant ';' */
5992 /* XXX: find more elegant solution */
5997 /* special test for old K&R protos without explicit int
5998 type. Only accepted when defining global data */
5999 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6003 if (((b
& VT_BTYPE
) == VT_ENUM
||
6004 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6006 /* we accept no variable after */
6010 while (1) { /* iterate thru each declaration */
6011 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6015 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6016 printf("type = '%s'\n", buf
);
6020 #ifdef CONFIG_REG_VARS
6021 TokenString func_str
;
6022 ParseState saved_parse_state
;
6027 error("cannot use local functions");
6029 expect("function definition");
6031 #ifdef CONFIG_REG_VARS
6032 /* parse all function code and record it */
6034 tok_str_new(&func_str
);
6040 error("unexpected end of file");
6041 tok_str_add_tok(&func_str
);
6046 } else if (t
== '}') {
6048 if (block_level
== 0)
6052 tok_str_add(&func_str
, -1);
6053 tok_str_add(&func_str
, 0);
6055 save_parse_state(&saved_parse_state
);
6057 macro_ptr
= func_str
.str
;
6062 /* compute text section */
6063 cur_text_section
= ad
.section
;
6064 if (!cur_text_section
)
6065 cur_text_section
= text_section
;
6066 ind
= (int)cur_text_section
->data_ptr
;
6067 funcname
= get_tok_str(v
, NULL
);
6070 /* if symbol is already defined, then put complete type */
6073 /* put function symbol */
6074 sym
= sym_push1(&global_stack
, v
, t
, 0);
6076 put_extern_sym(sym
, cur_text_section
,
6077 ind
- (int)cur_text_section
->data
);
6078 sym
->r
= VT_SYM
| VT_CONST
;
6079 /* put debug symbol */
6082 /* push a dummy symbol to enable local sym storage */
6083 sym_push1(&local_stack
, 0, 0, 0);
6087 #ifdef CONFIG_REG_VARS
6088 macro_ptr
= func_str
.str
;
6091 block(NULL
, NULL
, NULL
, NULL
, 0);
6094 cur_text_section
->data_ptr
= (unsigned char *)ind
;
6095 sym_pop(&label_stack
, NULL
); /* reset label stack */
6096 sym_pop(&local_stack
, NULL
); /* reset local stack */
6097 /* end of function */
6099 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6101 funcname
= ""; /* for safety */
6102 func_vt
= VT_VOID
; /* for safety */
6103 ind
= 0; /* for safety */
6105 #ifdef CONFIG_REG_VARS
6107 restore_parse_state(&saved_parse_state
);
6111 if (b
& VT_TYPEDEF
) {
6112 /* save typedefed type */
6113 /* XXX: test storage specifiers ? */
6114 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6115 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6116 /* external function definition */
6117 external_sym(v
, t
, 0);
6119 /* not lvalue if array */
6121 if (!(t
& VT_ARRAY
))
6122 r
|= lvalue_type(t
);
6123 if (b
& VT_EXTERN
) {
6124 /* external variable */
6125 external_sym(v
, t
, r
);
6131 has_init
= (tok
== '=');
6134 decl_initializer_alloc(t
, &ad
, r
,
6148 /* compile the C file opened in 'file'. Return non zero if errors. */
6149 int tcc_compile(TCCState
*s
)
6155 include_stack_ptr
= include_stack
;
6156 ifdef_stack_ptr
= ifdef_stack
;
6159 anon_sym
= SYM_FIRST_ANOM
;
6161 /* file info: full path + filename */
6163 getcwd(buf
, sizeof(buf
));
6164 pstrcat(buf
, sizeof(buf
), "/");
6165 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6166 put_stabs(file
->filename
, N_SO
, 0, 0,
6167 (unsigned long)text_section
->data_ptr
);
6169 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6170 symbols can be safely used */
6171 put_elf_sym(symtab_section
, 0, 0,
6172 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6173 SHN_ABS
, file
->filename
);
6175 /* define common 'char *' type because it is often used internally
6176 for arrays and struct dereference */
6177 char_pointer_type
= mk_pointer(VT_BYTE
);
6179 define_start
= define_stack
.top
;
6181 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6185 expect("declaration");
6187 /* end of translation unit info */
6189 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6192 /* reset define stack, but leave -Dsymbols (may be incorrect if
6193 they are undefined) */
6194 sym_pop(&define_stack
, define_start
);
6196 sym_pop(&global_stack
, NULL
);
6201 int tcc_compile_file(TCCState
*s
, const char *filename1
)
6204 file
= tcc_open(filename1
);
6206 error("file '%s' not found", filename1
);
6207 ret
= tcc_compile(s
);
6212 int tcc_compile_string(TCCState
*s
, const char *str
)
6214 BufferedFile bf1
, *bf
= &bf1
;
6217 /* init file structure */
6219 bf
->buf_ptr
= (char *)str
;
6220 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6221 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6225 ret
= tcc_compile(s
);
6227 /* currently, no need to close */
6231 /* define a symbol. A value can also be provided with the '=' operator */
6232 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6234 BufferedFile bf1
, *bf
= &bf1
;
6236 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6237 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6241 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6243 /* init file structure */
6245 bf
->buf_ptr
= bf
->buffer
;
6246 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6247 bf
->filename
[0] = '\0';
6251 include_stack_ptr
= include_stack
;
6253 /* parse with define parser */
6255 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6261 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6265 ts
= tok_alloc(sym
, 0);
6266 s
= sym_find1(&define_stack
, tok
);
6267 /* undefine symbol by putting an invalid name */
6269 sym_undef(&define_stack
, s
);
6272 /* open a dynamic library so that its symbol are available for
6273 compiled programs */
6274 /* XXX: open the lib only to actually run the program */
6275 int tcc_add_dll(TCCState
*s
, const char *library_name
)
6279 h
= dlopen(library_name
, RTLD_GLOBAL
| RTLD_LAZY
);
6281 error((char *)dlerror());
6285 static int put_elf_str(Section
*s
, const char *sym
)
6288 offset
= s
->data_ptr
- s
->data
;
6298 /* elf symbol hashing function */
6299 static unsigned long elf_hash(const unsigned char *name
)
6301 unsigned long h
= 0, g
;
6304 h
= (h
<< 4) + *name
++;
6313 /* return the symbol number */
6314 static int put_elf_sym(Section
*s
,
6315 unsigned long value
, unsigned long size
,
6316 int info
, int other
, int shndx
, const char *name
)
6318 int name_offset
, nbuckets
, h
, sym_index
;
6322 sym
= (Elf32_Sym
*)s
->data_ptr
;
6324 name_offset
= put_elf_str(s
->link
, name
);
6327 /* XXX: endianness */
6328 sym
->st_name
= name_offset
;
6329 sym
->st_value
= value
;
6330 sym
->st_size
= size
;
6331 sym
->st_info
= info
;
6332 sym
->st_other
= other
;
6333 sym
->st_shndx
= shndx
;
6334 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6336 if (hs
&& ELF32_ST_BIND(info
) == STB_GLOBAL
) {
6337 /* add another hashing entry */
6338 nbuckets
= ((int *)hs
->data
)[0];
6339 ((int *)hs
->data
)[1]++;
6340 h
= elf_hash(name
) % nbuckets
;
6341 ((int *)hs
->data
)[2 + nbuckets
+ sym_index
] = ((int *)hs
->data
)[2 + h
];
6342 ((int *)hs
->data
)[2 + h
] = sym_index
;
6344 s
->data_ptr
+= sizeof(Elf32_Sym
);
6348 /* find global ELF symbol 'name' and return its index. Return 0 if not
6350 static int find_elf_sym(Section
*s
, const char *name
)
6354 int nbuckets
, sym_index
, h
;
6360 nbuckets
= ((int *)hs
->data
)[0];
6361 h
= elf_hash(name
) % nbuckets
;
6362 sym_index
= ((int *)hs
->data
)[2 + h
];
6363 while (sym_index
!= 0) {
6364 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6365 name1
= s
->link
->data
+ sym
->st_name
;
6366 if (!strcmp(name
, name1
))
6368 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6373 /* update sym->c so that it points to an external symbol in section
6374 'section' with value 'value' */
6375 /* XXX: get rid of put_elf_sym */
6376 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
)
6378 int sym_type
, sym_bind
, sh_num
;
6383 sh_num
= section
->sh_num
;
6387 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6388 sym_type
= STT_FUNC
;
6390 sym_type
= STT_OBJECT
;
6391 if (sym
->t
& VT_STATIC
)
6392 sym_bind
= STB_LOCAL
;
6394 sym_bind
= STB_GLOBAL
;
6395 /* if the symbol is global, then we look if it is already
6397 name
= get_tok_str(sym
->v
, NULL
);
6398 if (sym_bind
== STB_GLOBAL
) {
6399 sym
->c
= find_elf_sym(symtab_section
, name
);
6402 /* check if not defined */
6404 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6405 if (esym
->st_shndx
!= SHN_UNDEF
)
6406 error("'%s' defined twice", name
);
6407 esym
->st_shndx
= sh_num
;
6408 esym
->st_value
= value
;
6412 sym
->c
= put_elf_sym(symtab_section
, value
, 0,
6413 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6417 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6418 esym
->st_value
= value
;
6419 esym
->st_shndx
= sh_num
;
6423 /* put relocation */
6424 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
6425 int type
, int symbol
)
6433 /* if no relocation section, create it */
6434 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6435 sr
= new_section(buf
, SHT_REL
, s
->sh_flags
);
6436 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6438 sr
->sh_info
= s
->sh_num
;
6441 rel
= (Elf32_Rel
*)sr
->data_ptr
;
6442 /* XXX: endianness */
6443 rel
->r_offset
= offset
;
6444 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6445 sr
->data_ptr
+= sizeof(Elf32_Rel
);
6448 /* put stab debug information */
6451 unsigned long n_strx
; /* index into string table of name */
6452 unsigned char n_type
; /* type of symbol */
6453 unsigned char n_other
; /* misc info (usually empty) */
6454 unsigned short n_desc
; /* description field */
6455 unsigned long n_value
; /* value of symbol */
6458 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
6462 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
6464 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6469 sym
->n_other
= other
;
6471 sym
->n_value
= value
;
6473 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
6476 static void put_stabn(int type
, int other
, int desc
, int value
)
6478 put_stabs(NULL
, type
, other
, desc
, value
);
6481 static void put_stabd(int type
, int other
, int desc
)
6483 put_stabs(NULL
, type
, other
, desc
, 0);
6486 /* In an ELF file symbol table, the local symbols must appear below
6487 the global and weak ones. Since TCC cannot sort it while generating
6488 the code, we must do it after. All the relocation tables are also
6489 modified to take into account the symbol table sorting */
6490 static void sort_symbols(Section
*s
)
6492 int *old_to_new_syms
;
6493 Elf32_Sym
*new_syms
;
6498 int type
, sym_index
;
6500 nb_syms
= (s
->data_ptr
- s
->data
) / sizeof(Elf32_Sym
);
6501 new_syms
= malloc(nb_syms
* sizeof(Elf32_Sym
));
6503 error("memory full");
6504 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
6505 if (!old_to_new_syms
)
6506 error("memory full");
6507 /* first pass for local symbols */
6508 p
= (Elf32_Sym
*)s
->data
;
6510 for(i
= 0; i
< nb_syms
; i
++) {
6511 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
6512 old_to_new_syms
[i
] = q
- new_syms
;
6517 /* save the number of local symbols in section header */
6518 s
->sh_info
= q
- new_syms
;
6520 /* then second pass for non local symbols */
6521 p
= (Elf32_Sym
*)s
->data
;
6522 for(i
= 0; i
< nb_syms
; i
++) {
6523 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
6524 old_to_new_syms
[i
] = q
- new_syms
;
6530 /* we copy the new symbols to the old */
6531 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
6534 /* now we modify all the relocations */
6535 for(sr
= first_section
; sr
!= NULL
; sr
= sr
->next
) {
6536 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
6537 for(rel
= (Elf32_Rel
*)sr
->data
;
6538 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6540 sym_index
= ELF32_R_SYM(rel
->r_info
);
6541 type
= ELF32_R_TYPE(rel
->r_info
);
6542 sym_index
= old_to_new_syms
[sym_index
];
6543 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
6548 free(old_to_new_syms
);
6551 static Section
*new_section_hash(const char *name
, int sh_flags
,
6552 int nb_buckets
, Section
*symtab
)
6555 hash
= new_section(name
, SHT_HASH
, sh_flags
);
6556 ((int *)hash
->data
)[0] = nb_buckets
;
6557 ((int *)hash
->data
)[1] = 1;
6558 hash
->sh_entsize
= sizeof(int);
6559 hash
->data_ptr
+= (2 + nb_buckets
+ 1) * sizeof(int);
6560 symtab
->hash
= hash
;
6561 hash
->link
= symtab
;
6565 /* put dynamic tag */
6566 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
6569 dyn
= (Elf32_Dyn
*)dynamic
->data_ptr
;
6571 dyn
->d_un
.d_val
= val
;
6572 dynamic
->data_ptr
+= sizeof(Elf32_Dyn
);
6575 /* add dynamic sections so that the executable is dynamically linked */
6576 static char elf_interp
[] = "/lib/ld-linux.so.2";
6578 #define ELF_START_ADDR 0x08048000
6579 #define ELF_PAGE_SIZE 0x1000
6581 /* XXX: suppress that */
6582 static void put32(unsigned char *p
, unsigned int val
)
6590 /* output an ELF file (currently, only for testing) */
6591 /* XXX: generate startup code */
6592 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6593 int tcc_output_file(TCCState
*s1
, const char *filename
, int file_type
)
6599 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
;
6601 Section
*strsec
, *s
;
6602 Elf32_Shdr shdr
, *sh
;
6603 Elf32_Phdr
*phdr
, *ph
;
6604 Section
*interp
, *plt
, *got
, *dynamic
, *dynsym
, *dynstr
, *hash
;
6605 unsigned char *saved_dynamic_data_ptr
;
6611 plt
= NULL
; /* avoid warning */
6612 got
= NULL
; /* avoid warning */
6613 dynsym
= NULL
; /* avoid warning */
6614 hash
= NULL
; /* avoid warning */
6615 dynstr
= NULL
; /* avoid warning */
6616 saved_dynamic_data_ptr
= NULL
; /* avoid warning */
6618 if (file_type
!= TCC_FILE_OBJ
&& !static_link
) {
6622 if (file_type
== TCC_FILE_EXE
) {
6623 /* add interpreter section only if executable */
6624 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
6625 interp
->sh_addralign
= 1;
6626 strcpy(interp
->data_ptr
, elf_interp
);
6627 interp
->data_ptr
+= sizeof(elf_interp
);
6630 /* add dynamic symbol table */
6631 dynsym
= new_section(".dynsym", SHT_DYNSYM
, SHF_ALLOC
);
6632 dynsym
->sh_entsize
= sizeof(Elf32_Sym
);
6633 dynstr
= new_section(".dynstr", SHT_STRTAB
, SHF_ALLOC
);
6634 put_elf_str(dynstr
, "");
6635 dynsym
->link
= dynstr
;
6636 put_elf_sym(dynsym
, 0, 0, 0, 0, 0, NULL
);
6639 hash
= new_section_hash(".hash", SHF_ALLOC
,
6640 ELF_DYNSYM_HASH_SIZE
, dynsym
);
6642 /* add dynamic section */
6643 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
6644 SHF_ALLOC
| SHF_WRITE
);
6645 dynamic
->link
= dynstr
;
6646 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
6648 /* add PLT and GOT */
6649 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6650 plt
->sh_entsize
= 4;
6651 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6652 got
->sh_entsize
= 4;
6654 /* add undefined symbols in dynamic symbol table */
6656 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6657 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6659 if (sym
->st_shndx
== SHN_UNDEF
) {
6660 name
= symtab_section
->link
->data
+ sym
->st_name
;
6661 type
= ELF32_ST_TYPE(sym
->st_info
);
6662 put_elf_sym(dynsym
, 0, 0,
6663 sym
->st_info
, 0, SHN_UNDEF
, name
);
6664 if (type
== STT_FUNC
) {
6666 /* prepare space for relocation */
6667 put_elf_reloc(dynsym
, got
, 0, 0, 0);
6672 /* update PLT/GOT sizes so that we can allocate their space */
6673 plt
->data_ptr
+= 16 * (nb_plt_entries
+ 1);
6674 got
->data_ptr
+= 4 * (nb_plt_entries
+ 3);
6676 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, "libc.so.6"));
6677 /* XXX: add other libs */
6679 /* add necessary space for other entries */
6680 saved_dynamic_data_ptr
= dynamic
->data_ptr
;
6681 dynamic
->data_ptr
+= 8 * 9;
6684 sort_symbols(symtab_section
);
6686 memset(&ehdr
, 0, sizeof(ehdr
));
6688 /* we add a section for symbols */
6689 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
6690 put_elf_str(strsec
, "");
6692 /* compute number of sections */
6693 shnum
= nb_sections
;
6695 /* this array is used to reorder sections in the output file */
6696 section_order
= malloc(sizeof(int) * shnum
);
6698 error("memory full");
6699 section_order
[0] = 0;
6702 /* compute number of program headers */
6719 /* allocate strings for section names */
6720 for(i
= 1; i
< nb_sections
; i
++) {
6722 s
->sh_name
= put_elf_str(strsec
, s
->name
);
6723 s
->sh_size
= s
->data_ptr
- s
->data
;
6726 /* allocate program segment headers */
6727 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
6729 error("memory full");
6730 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
6732 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6734 /* compute section to program header mapping */
6735 if (file_type
== TCC_FILE_DLL
)
6738 addr
= ELF_START_ADDR
;
6740 /* compute address after headers */
6741 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
6743 /* leave one program header for the program interpreter */
6748 for(j
= 0; j
< 2; j
++) {
6749 ph
->p_type
= PT_LOAD
;
6751 ph
->p_flags
= PF_R
| PF_X
;
6753 ph
->p_flags
= PF_R
| PF_W
;
6754 ph
->p_align
= ELF_PAGE_SIZE
;
6756 for(i
= 1; i
< nb_sections
; i
++) {
6758 /* compute if section should be included */
6760 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
6764 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
6765 (SHF_ALLOC
| SHF_WRITE
))
6768 section_order
[sh_order_index
++] = i
;
6770 /* section matches: we align it and add its size */
6772 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
6773 ~(s
->sh_addralign
- 1);
6774 s
->sh_offset
= file_offset
;
6775 addr
+= file_offset
- tmp
;
6778 if (ph
->p_offset
== 0) {
6779 ph
->p_offset
= file_offset
;
6781 ph
->p_paddr
= ph
->p_vaddr
;
6784 file_offset
+= s
->sh_size
;
6786 ph
->p_filesz
= file_offset
- ph
->p_offset
;
6787 ph
->p_memsz
= addr
- ph
->p_vaddr
;
6791 /* if interpreter, then add corresponing program header */
6795 ph
->p_type
= PT_INTERP
;
6796 ph
->p_offset
= interp
->sh_offset
;
6797 ph
->p_vaddr
= interp
->sh_addr
;
6798 ph
->p_paddr
= ph
->p_vaddr
;
6799 ph
->p_filesz
= interp
->sh_size
;
6800 ph
->p_memsz
= interp
->sh_size
;
6802 ph
->p_align
= interp
->sh_addralign
;
6805 /* if dynamic section, then add corresponing program header */
6807 int sym_index
, plt_offset
;
6810 ph
= &phdr
[phnum
- 1];
6812 ph
->p_type
= PT_DYNAMIC
;
6813 ph
->p_offset
= dynamic
->sh_offset
;
6814 ph
->p_vaddr
= dynamic
->sh_addr
;
6815 ph
->p_paddr
= ph
->p_vaddr
;
6816 ph
->p_filesz
= dynamic
->sh_size
;
6817 ph
->p_memsz
= dynamic
->sh_size
;
6818 ph
->p_flags
= PF_R
| PF_W
;
6819 ph
->p_align
= dynamic
->sh_addralign
;
6821 /* now all the sections are mapped, so we can compute all
6824 /* first three got entries */
6825 got
->data_ptr
= got
->data
;
6826 plt
->data_ptr
= plt
->data
;
6828 got
->reloc
->data_ptr
= got
->reloc
->data
;
6830 put32(got
->data_ptr
, dynamic
->sh_addr
);
6832 put32(got
->data_ptr
, 0);
6834 put32(got
->data_ptr
, 0);
6837 /* first plt entry */
6839 p
[0] = 0xff; /* pushl got + 4 */
6841 put32(p
+ 2, got
->sh_addr
+ 4);
6842 p
[6] = 0xff; /* jmp *(got + 8) */
6844 put32(p
+ 8, got
->sh_addr
+ 8);
6845 plt
->data_ptr
+= 16;
6847 /* add undefined symbols in dynamic symbol table. also update
6848 PLT and GOT if needed */
6851 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
6852 sym
< (Elf32_Sym
*)dynsym
->data_ptr
;
6854 type
= ELF32_ST_TYPE(sym
->st_info
);
6855 if (type
== STT_FUNC
) {
6856 /* one more entry in PLT */
6858 p
[0] = 0xff; /* jmp *(got + x) */
6860 put32(p
+ 2, got
->sh_addr
+ got
->data_ptr
- got
->data
);
6861 p
[6] = 0x68; /* push $xxx */
6862 put32(p
+ 7, plt_offset
);
6863 p
[11] = 0xe9; /* jmp plt_start */
6864 put32(p
+ 12, -(plt
->data_ptr
+ 16 - plt
->data
));
6866 /* patch symbol value to point to plt */
6867 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
6870 plt
->data_ptr
+= 16;
6872 /* corresponding got entry */
6873 put_elf_reloc(dynsym
, got
,
6874 got
->sh_addr
+ got
->data_ptr
- got
->data
,
6877 put32(got
->data_ptr
, 0);
6882 /* put dynamic section entries */
6884 dynamic
->data_ptr
= saved_dynamic_data_ptr
;
6885 put_dt(dynamic
, DT_HASH
, hash
->sh_addr
);
6886 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
6887 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
6888 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_ptr
- dynstr
->data
);
6889 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
6890 put_dt(dynamic
, DT_REL
, got
->reloc
->sh_addr
);
6891 put_dt(dynamic
, DT_RELSZ
, got
->reloc
->data_ptr
- got
->reloc
->data
);
6892 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
6893 put_dt(dynamic
, DT_NULL
, 0);
6896 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
6897 ehdr
.e_phnum
= phnum
;
6898 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
6901 /* all other sections come after */
6902 for(i
= 1; i
< nb_sections
; i
++) {
6904 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
6906 section_order
[sh_order_index
++] = i
;
6908 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
6909 ~(s
->sh_addralign
- 1);
6910 s
->sh_offset
= file_offset
;
6911 file_offset
+= s
->sh_size
;
6915 file_offset
= (file_offset
+ 3) & -4;
6918 ehdr
.e_ident
[0] = ELFMAG0
;
6919 ehdr
.e_ident
[1] = ELFMAG1
;
6920 ehdr
.e_ident
[2] = ELFMAG2
;
6921 ehdr
.e_ident
[3] = ELFMAG3
;
6922 ehdr
.e_ident
[4] = ELFCLASS32
;
6923 ehdr
.e_ident
[5] = ELFDATA2LSB
;
6924 ehdr
.e_ident
[6] = EV_CURRENT
;
6928 ehdr
.e_type
= ET_EXEC
;
6931 ehdr
.e_type
= ET_DYN
;
6934 ehdr
.e_type
= ET_REL
;
6937 ehdr
.e_machine
= EM_386
;
6938 ehdr
.e_version
= EV_CURRENT
;
6939 ehdr
.e_entry
= 0; /* XXX: patch it */
6940 ehdr
.e_shoff
= file_offset
;
6941 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
6942 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
6943 ehdr
.e_shnum
= shnum
;
6944 ehdr
.e_shstrndx
= shnum
- 1;
6946 /* write elf file */
6947 if (file_type
== TCC_FILE_OBJ
)
6951 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
6953 error("could not write '%s'", filename
);
6955 f
= fdopen(fd
, "w");
6956 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
6957 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
6958 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6959 for(i
=1;i
<nb_sections
;i
++) {
6960 s
= sections
[section_order
[i
]];
6961 while (offset
< s
->sh_offset
) {
6965 size
= s
->data_ptr
- s
->data
;
6966 fwrite(s
->data
, 1, size
, f
);
6969 while (offset
< ehdr
.e_shoff
) {
6974 /* output sections */
6975 for(i
=0;i
<nb_sections
;i
++) {
6977 memset(sh
, 0, sizeof(Elf32_Shdr
));
6980 sh
->sh_name
= s
->sh_name
;
6981 sh
->sh_type
= s
->sh_type
;
6982 sh
->sh_flags
= s
->sh_flags
;
6983 sh
->sh_entsize
= s
->sh_entsize
;
6984 sh
->sh_info
= s
->sh_info
;
6986 sh
->sh_link
= s
->link
->sh_num
;
6987 sh
->sh_addralign
= s
->sh_addralign
;
6988 sh
->sh_addr
= s
->sh_addr
;
6989 sh
->sh_offset
= s
->sh_offset
;
6990 sh
->sh_size
= s
->sh_size
;
6992 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
6996 free(section_order
);
7001 /* print the position in the source file of PC value 'pc' by reading
7002 the stabs debug information */
7003 static void rt_printline(unsigned long wanted_pc
)
7005 Stab_Sym
*sym
, *sym_end
;
7006 char func_name
[128];
7007 unsigned long func_addr
, last_pc
, pc
;
7008 const char *incl_files
[INCLUDE_STACK_SIZE
];
7009 int incl_index
, len
, last_line_num
, i
;
7010 const char *str
, *p
;
7012 func_name
[0] = '\0';
7015 last_pc
= 0xffffffff;
7017 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7018 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
7019 while (sym
< sym_end
) {
7020 switch(sym
->n_type
) {
7021 /* function start or end */
7023 if (sym
->n_strx
== 0) {
7024 func_name
[0] = '\0';
7027 str
= stabstr_section
->data
+ sym
->n_strx
;
7028 p
= strchr(str
, ':');
7030 pstrcpy(func_name
, sizeof(func_name
), str
);
7033 if (len
> sizeof(func_name
) - 1)
7034 len
= sizeof(func_name
) - 1;
7035 memcpy(func_name
, str
, len
);
7036 func_name
[len
] = '\0';
7038 func_addr
= sym
->n_value
;
7041 /* line number info */
7043 pc
= sym
->n_value
+ func_addr
;
7044 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7047 last_line_num
= sym
->n_desc
;
7051 str
= stabstr_section
->data
+ sym
->n_strx
;
7053 if (incl_index
< INCLUDE_STACK_SIZE
) {
7054 incl_files
[incl_index
++] = str
;
7062 if (sym
->n_strx
== 0) {
7063 incl_index
= 0; /* end of translation unit */
7065 str
= stabstr_section
->data
+ sym
->n_strx
;
7066 /* do not add path */
7068 if (len
> 0 && str
[len
- 1] != '/')
7075 /* did not find line number info: */
7076 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
7079 for(i
= 0; i
< incl_index
- 1; i
++)
7080 fprintf(stderr
, "In file included from %s\n",
7082 if (incl_index
> 0) {
7083 fprintf(stderr
, "%s:%d: ",
7084 incl_files
[incl_index
- 1], last_line_num
);
7086 if (func_name
[0] != '\0') {
7087 fprintf(stderr
, "in function '%s()': ", func_name
);
7091 /* emit a run time error at position 'pc' */
7092 void rt_error(unsigned long pc
, const char *fmt
, ...)
7098 vfprintf(stderr
, fmt
, ap
);
7099 fprintf(stderr
, "\n");
7105 /* signal handler for fatal errors */
7106 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7108 struct ucontext
*uc
= puc
;
7112 pc
= uc
->uc_mcontext
.gregs
[14];
7114 #error please put the right sigcontext field
7119 switch(siginf
->si_code
) {
7122 rt_error(pc
, "division by zero");
7125 rt_error(pc
, "floating point exception");
7131 rt_error(pc
, "dereferencing invalid pointer");
7134 rt_error(pc
, "illegal instruction");
7137 rt_error(pc
, "abort() called");
7140 rt_error(pc
, "caught signal %d", signum
);
7147 static void *resolve_sym(const char *sym
)
7149 #ifdef CONFIG_TCC_BCHECK
7150 if (do_bounds_check
) {
7152 ptr
= bound_resolve_sym(sym
);
7157 return dlsym(NULL
, sym
);
7160 static void resolve_extern_syms(void)
7166 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7167 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
7169 if (sym
->st_shndx
== SHN_UNDEF
) {
7170 name
= symtab_section
->link
->data
+ sym
->st_name
;
7171 addr
= (unsigned long)resolve_sym(name
);
7173 error("unresolved external reference '%s'", name
);
7174 sym
->st_value
= addr
;
7175 sym
->st_shndx
= SHN_ABS
;
7180 static unsigned long get_sym_val(int sym_index
)
7185 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
7186 val
= sym
->st_value
;
7187 if (sym
->st_shndx
!= SHN_ABS
)
7188 val
+= sections
[sym
->st_shndx
]->sh_addr
;
7192 /* relocate sections */
7193 static void relocate_section(Section
*s
)
7204 for(rel
= (Elf32_Rel
*)sr
->data
;
7205 rel
< (Elf32_Rel
*)sr
->data_ptr
;
7207 ptr
= s
->data
+ rel
->r_offset
;
7208 val
= get_sym_val(ELF32_R_SYM(rel
->r_info
));
7209 type
= ELF32_R_TYPE(rel
->r_info
);
7210 greloc_patch(ptr
, s
->sh_addr
+ rel
->r_offset
, val
, type
);
7214 /* relocate all the code and data */
7215 static void relocate_program(void)
7219 /* compute relocation address : section are relocated in place */
7220 for(s
= first_section
; s
!= NULL
; s
= s
->next
) {
7221 if (s
->sh_type
== SHT_PROGBITS
)
7222 s
->sh_addr
= (unsigned long)s
->data
;
7225 /* relocate each section */
7226 for(s
= first_section
; s
!= NULL
; s
= s
->next
) {
7227 if (s
->sh_type
== SHT_PROGBITS
)
7228 relocate_section(s
);
7232 /* launch the compiled program with the given arguments */
7233 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7235 int (*prog_main
)(int, char **);
7238 resolve_extern_syms();
7242 sym_index
= find_elf_sym(symtab_section
, "main");
7244 error("main() not defined");
7245 prog_main
= (void *)get_sym_val(sym_index
);
7249 error("debug mode currently not available for Windows");
7251 struct sigaction sigact
;
7252 /* install TCC signal handlers to print debug info on fatal
7254 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7255 sigact
.sa_sigaction
= sig_error
;
7256 sigemptyset(&sigact
.sa_mask
);
7257 sigaction(SIGFPE
, &sigact
, NULL
);
7258 sigaction(SIGILL
, &sigact
, NULL
);
7259 sigaction(SIGSEGV
, &sigact
, NULL
);
7260 sigaction(SIGBUS
, &sigact
, NULL
);
7261 sigaction(SIGABRT
, &sigact
, NULL
);
7265 #ifdef CONFIG_TCC_BCHECK
7266 if (do_bounds_check
) {
7269 /* add all known static regions */
7270 p
= (int *)bounds_section
->data
;
7271 p_end
= (int *)bounds_section
->data_ptr
;
7273 __bound_new_region((void *)p
[0], p
[1]);
7279 return (*prog_main
)(argc
, argv
);
7282 TCCState
*tcc_new(void)
7287 s
= malloc(sizeof(TCCState
));
7291 /* default include paths */
7292 nb_include_paths
= 0;
7293 tcc_add_include_path(s
, "/usr/include");
7294 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7296 /* add all tokens */
7297 tok_ident
= TOK_IDENT
;
7302 tok_alloc(p
, r
- p
- 1);
7306 /* standard defines */
7307 tcc_define_symbol(s
, "__STDC__", NULL
);
7309 tcc_define_symbol(s
, "__i386__", NULL
);
7311 /* tiny C specific defines */
7312 tcc_define_symbol(s
, "__TINYC__", NULL
);
7314 /* create standard sections */
7316 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7317 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7318 /* XXX: should change type to SHT_NOBITS */
7319 bss_section
= new_section(".bss", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7321 /* symbols are always generated for linking stage */
7322 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
7323 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
7324 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
7325 put_elf_str(strtab_section
, "");
7326 symtab_section
->link
= strtab_section
;
7327 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
7329 /* private hash table for extern symbols */
7330 new_section_hash(".hashtab", SHF_PRIVATE
,
7331 ELF_SYM_HASH_SIZE
, symtab_section
);
7335 void tcc_delete(TCCState
*s
)
7340 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
7344 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
7346 pathname1
= strdup(pathname
);
7349 include_paths
[nb_include_paths
++] = pathname1
;
7353 #if !defined(LIBTCC)
7357 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7358 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
7359 " [-i infile] [-bench] infile [infile_args...]\n"
7361 "-Idir : add include path 'dir'\n"
7362 "-Dsym[=val] : define 'sym' with value 'val'\n"
7363 "-Usym : undefine 'sym'\n"
7364 "-llib : link with dynamic library 'lib'\n"
7365 "-g : generate runtime debug info\n"
7366 #ifdef CONFIG_TCC_BCHECK
7367 "-b : compile with built-in memory and bounds checker (implies -g)\n"
7369 "-i infile : compile infile\n"
7370 "-bench : output compilation statistics\n"
7374 int main(int argc
, char **argv
)
7377 int optind
, file_type
;
7381 file_type
= TCC_FILE_EXE
;
7386 if (optind
>= argc
) {
7396 if (tcc_add_include_path(s
, r
+ 2) < 0)
7397 error("too many include paths");
7398 } else if (r
[1] == 'D') {
7401 value
= strchr(sym
, '=');
7406 tcc_define_symbol(s
, sym
, value
);
7407 } else if (r
[1] == 'U') {
7408 tcc_undefine_symbol(s
, r
+ 2);
7409 } else if (r
[1] == 'l') {
7411 snprintf(buf
, sizeof(buf
), "lib%s.so", r
+ 2);
7412 tcc_add_dll(s
, buf
);
7413 } else if (r
[1] == 'i') {
7416 tcc_compile_file(s
, argv
[optind
++]);
7417 } else if (!strcmp(r
+ 1, "bench")) {
7419 #ifdef CONFIG_TCC_BCHECK
7420 } else if (r
[1] == 'b') {
7421 if (!do_bounds_check
) {
7422 do_bounds_check
= 1;
7424 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7425 /* create bounds sections */
7426 bounds_section
= new_section(".bounds",
7427 SHT_PROGBITS
, SHF_ALLOC
);
7428 lbounds_section
= new_section(".lbounds",
7429 SHT_PROGBITS
, SHF_ALLOC
);
7430 /* debug is implied */
7434 } else if (r
[1] == 'g') {
7435 #ifdef CONFIG_TCC_BCHECK
7442 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
7443 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7444 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
7445 put_elf_str(stabstr_section
, "");
7446 stab_section
->link
= stabstr_section
;
7447 /* put first entry */
7448 put_stabs("", 0, 0, 0, 0);
7451 /* the following options are only for testing, so not
7454 file_type
= TCC_FILE_OBJ
;
7455 } else if (!strcmp(r
+ 1, "shared")) {
7456 file_type
= TCC_FILE_DLL
;
7457 } else if (r
[1] == 'o') {
7460 outfile
= argv
[optind
++];
7462 error("invalid option -- '%s'", r
);
7466 tcc_compile_file(s
, argv
[optind
]);
7469 printf("total: %d idents, %d lines, %d bytes\n",
7470 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7474 tcc_output_file(s
, outfile
, file_type
);
7477 return tcc_run(s
, argc
- optind
, argv
+ optind
);