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 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
65 executables or dlls */
66 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
68 /* amount of virtual memory associated to a section (currently, we do
70 #define SECTION_VSIZE (1024 * 1024)
72 #define INCLUDE_STACK_SIZE 32
73 #define IFDEF_STACK_SIZE 64
74 #define VSTACK_SIZE 64
75 #define STRING_MAX_SIZE 1024
76 #define INCLUDE_PATHS_MAX 32
78 #define TOK_HASH_SIZE 2048 /* must be a power of two */
79 #define TOK_ALLOC_INCR 512 /* must be a power of two */
80 #define SYM_HASH_SIZE 1031
81 #define ELF_SYM_HASH_SIZE 2048
82 #define ELF_DYNSYM_HASH_SIZE 32
84 /* token symbol management */
85 typedef struct TokenSym
{
86 struct TokenSym
*hash_next
;
87 int tok
; /* token number */
93 typedef union CValue
{
99 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
101 unsigned long long ull
;
108 typedef struct SValue
{
110 unsigned short r
; /* register + flags */
111 unsigned short r2
; /* second register, used for 'long long'
112 type. If not used, set to VT_CONST */
113 CValue c
; /* constant, if VT_CONST */
116 /* symbol management */
118 int v
; /* symbol token */
119 int t
; /* associated type */
120 int r
; /* associated register */
121 int c
; /* associated number */
122 struct Sym
*next
; /* next related symbol */
123 struct Sym
*prev
; /* prev symbol in stack */
124 struct Sym
*hash_next
; /* next symbol in hash table */
127 typedef struct SymStack
{
129 struct Sym
*hash
[SYM_HASH_SIZE
];
132 /* section definition */
133 /* XXX: use directly ELF structure for parameters ? */
134 /* special flag to indicate that the section should not be linked to
136 #define SHF_PRIVATE 0x80000000
138 typedef struct Section
{
139 unsigned char *data
; /* section data */
140 unsigned char *data_ptr
; /* current data pointer */
141 int sh_name
; /* elf section name (only used during output) */
142 int sh_num
; /* elf section number */
143 int sh_type
; /* elf section type */
144 int sh_flags
; /* elf section flags */
145 int sh_info
; /* elf section info */
146 int sh_addralign
; /* elf section alignment */
147 int sh_entsize
; /* elf entry size */
148 unsigned long sh_size
; /* section size (only used during output) */
149 unsigned long sh_addr
; /* address at which the section is relocated */
150 unsigned long sh_offset
; /* address at which the section is relocated */
151 struct Section
*link
; /* link to another section */
152 struct Section
*reloc
; /* corresponding section for relocation, if any */
153 struct Section
*hash
; /* hash table for symbols */
154 struct Section
*next
;
155 char name
[64]; /* section name */
158 /* GNUC attribute definition */
159 typedef struct AttributeDef
{
162 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
165 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
166 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
167 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
169 /* stored in 'Sym.c' field */
170 #define FUNC_NEW 1 /* ansi function prototype */
171 #define FUNC_OLD 2 /* old function prototype */
172 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
174 /* stored in 'Sym.r' field */
175 #define FUNC_CDECL 0 /* standard c call */
176 #define FUNC_STDCALL 1 /* pascal c call */
178 /* field 'Sym.t' for macros */
179 #define MACRO_OBJ 0 /* object like macro */
180 #define MACRO_FUNC 1 /* function like macro */
182 /* field 'Sym.t' for labels */
183 #define LABEL_FORWARD 1 /* label is forward defined */
185 /* type_decl() types */
186 #define TYPE_ABSTRACT 1 /* type without variable */
187 #define TYPE_DIRECT 2 /* type with variable */
189 #define IO_BUF_SIZE 8192
191 typedef struct BufferedFile
{
192 unsigned char *buf_ptr
;
193 unsigned char *buf_end
;
195 int line_num
; /* current line number - here to simply code */
196 char filename
[1024]; /* current filename - here to simply code */
197 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
200 #define CH_EOB 0 /* end of buffer or '\0' char in file */
201 #define CH_EOF (-1) /* end of file */
203 /* parsing state (used to save parser state to reparse part of the
204 source several times) */
205 typedef struct ParseState
{
212 /* used to record tokens */
213 typedef struct TokenString
{
220 struct BufferedFile
*file
;
221 int ch
, ch1
, tok
, tok1
;
225 /* XXX: suppress first_section */
226 Section
*first_section
, **sections
;
227 int nb_sections
; /* number of sections, including first dummy section */
228 int nb_allocated_sections
;
229 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
230 Section
*cur_text_section
; /* current section where function code is
232 /* bound check related sections */
233 Section
*bounds_section
; /* contains global data bound description */
234 Section
*lbounds_section
; /* contains local data bound description */
235 /* symbol sections */
236 Section
*symtab_section
, *strtab_section
;
239 Section
*stab_section
, *stabstr_section
;
241 /* loc : local variable index
242 ind : output code index
244 anon_sym: anonymous symbol index
247 prog
, ind
, loc
, const_wanted
;
248 int global_expr
; /* true if compound literals must be allocated
249 globally (used during initializers parsing */
250 int func_vt
, func_vc
; /* current function return type (used by
251 return instruction) */
252 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
254 TokenSym
**table_ident
;
255 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
256 char token_buf
[STRING_MAX_SIZE
+ 1];
258 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
260 SValue vstack
[VSTACK_SIZE
], *vtop
;
261 int *macro_ptr
, *macro_ptr_allocated
;
262 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
263 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
264 char *include_paths
[INCLUDE_PATHS_MAX
];
265 int nb_include_paths
;
266 int char_pointer_type
;
268 /* compile with debug symbol (and use them if error during execution) */
271 /* compile with built-in memory and bounds checker */
272 int do_bounds_check
= 0;
274 /* display benchmark infos */
279 /* use GNU C extensions */
282 /* use Tiny C extensions */
285 /* if true, static linking is performed */
292 /* The current value can be: */
293 #define VT_VALMASK 0x00ff
294 #define VT_CONST 0x00f0 /* constant in vc
295 (must be first non register value) */
296 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
297 #define VT_LOCAL 0x00f2 /* offset on stack */
298 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
299 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
300 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
301 #define VT_LVAL 0x0100 /* var is an lvalue */
302 #define VT_SYM 0x0200 /* a symbol value is added */
303 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
304 char/short stored in integer registers) */
305 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
306 dereferencing value */
307 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
308 bounding function call point is in vc */
309 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
310 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
311 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
312 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
315 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
317 #define VT_INT 0 /* integer type */
318 #define VT_BYTE 1 /* signed byte type */
319 #define VT_SHORT 2 /* short type */
320 #define VT_VOID 3 /* void type */
321 #define VT_PTR 4 /* pointer */
322 #define VT_ENUM 5 /* enum definition */
323 #define VT_FUNC 6 /* function type */
324 #define VT_STRUCT 7 /* struct/union definition */
325 #define VT_FLOAT 8 /* IEEE float */
326 #define VT_DOUBLE 9 /* IEEE double */
327 #define VT_LDOUBLE 10 /* IEEE long double */
328 #define VT_BOOL 11 /* ISOC99 boolean type */
329 #define VT_LLONG 12 /* 64 bit integer */
330 #define VT_LONG 13 /* long integer (NEVER USED as type, only
332 #define VT_BTYPE 0x000f /* mask for basic type */
333 #define VT_UNSIGNED 0x0010 /* unsigned type */
334 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
335 #define VT_BITFIELD 0x0040 /* bitfield modifier */
338 #define VT_EXTERN 0x00000080 /* extern definition */
339 #define VT_STATIC 0x00000100 /* static variable */
340 #define VT_TYPEDEF 0x00000200 /* typedef definition */
342 /* type mask (except storage) */
343 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
347 /* warning: the following compare tokens depend on i386 asm code */
359 #define TOK_LAND 0xa0
363 #define TOK_MID 0xa3 /* inc/dec, to void constant */
365 #define TOK_UDIV 0xb0 /* unsigned division */
366 #define TOK_UMOD 0xb1 /* unsigned modulo */
367 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
368 #define TOK_CINT 0xb3 /* number in tokc */
369 #define TOK_CCHAR 0xb4 /* char constant in tokc */
370 #define TOK_STR 0xb5 /* pointer to string in tokc */
371 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
372 #define TOK_LCHAR 0xb7
373 #define TOK_LSTR 0xb8
374 #define TOK_CFLOAT 0xb9 /* float constant */
375 #define TOK_LINENUM 0xba /* line number info */
376 #define TOK_CDOUBLE 0xc0 /* double constant */
377 #define TOK_CLDOUBLE 0xc1 /* long double constant */
378 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
379 #define TOK_ADDC1 0xc3 /* add with carry generation */
380 #define TOK_ADDC2 0xc4 /* add with carry use */
381 #define TOK_SUBC1 0xc5 /* add with carry generation */
382 #define TOK_SUBC2 0xc6 /* add with carry use */
383 #define TOK_CUINT 0xc8 /* unsigned int constant */
384 #define TOK_CLLONG 0xc9 /* long long constant */
385 #define TOK_CULLONG 0xca /* unsigned long long constant */
386 #define TOK_ARROW 0xcb
387 #define TOK_DOTS 0xcc /* three dots */
388 #define TOK_SHR 0xcd /* unsigned shift right */
390 #define TOK_SHL 0x01 /* shift left */
391 #define TOK_SAR 0x02 /* signed shift right */
393 /* assignement operators : normal operator or 0x80 */
394 #define TOK_A_MOD 0xa5
395 #define TOK_A_AND 0xa6
396 #define TOK_A_MUL 0xaa
397 #define TOK_A_ADD 0xab
398 #define TOK_A_SUB 0xad
399 #define TOK_A_DIV 0xaf
400 #define TOK_A_XOR 0xde
401 #define TOK_A_OR 0xfc
402 #define TOK_A_SHL 0x81
403 #define TOK_A_SAR 0x82
405 #define TOK_EOF (-1) /* end of file */
407 /* all identificators and strings have token above that */
408 #define TOK_IDENT 256
429 /* ignored types Must have contiguous values */
435 TOK___SIGNED__
, /* gcc keyword */
438 TOK___INLINE__
, /* gcc keyword */
441 /* unsupported type */
455 /* preprocessor only */
456 TOK_UIDENT
, /* first "user" ident (not keyword) */
457 TOK_DEFINE
= TOK_UIDENT
,
473 /* special identifiers */
476 /* attribute identifiers */
494 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
495 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
496 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
497 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
498 "sizeof\0__attribute__\0"
499 /* the following are not keywords. They are included to ease parsing */
500 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
501 "defined\0undef\0error\0line\0"
502 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
505 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
506 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
507 "noreturn\0__noreturn__\0"
511 #define snprintf _snprintf
514 #if defined(WIN32) || defined(TCC_UCLIBC)
515 /* currently incorrect */
516 long double strtold(const char *nptr
, char **endptr
)
518 return (long double)strtod(nptr
, endptr
);
520 float strtof(const char *nptr
, char **endptr
)
522 return (float)strtod(nptr
, endptr
);
525 /* XXX: need to define this to use them in non ISOC99 context */
526 extern float strtof (const char *__nptr
, char **__endptr
);
527 extern long double strtold (const char *__nptr
, char **__endptr
);
530 char *pstrcpy(char *buf
, int buf_size
, const char *s
);
531 char *pstrcat(char *buf
, int buf_size
, const char *s
);
535 void next_nomacro(void);
536 int expr_const(void);
540 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
541 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
544 void gv2(int rc1
, int rc2
);
545 void move_reg(int r
, int s
);
546 void save_regs(int n
);
547 void save_reg(int r
);
553 void macro_subst(TokenString
*tok_str
,
554 Sym
**nested_list
, int *macro_str
);
555 int save_reg_forced(int r
);
557 void force_charshort_cast(int t
);
558 void gen_cast(int t
);
560 Sym
*sym_find(int v
);
561 Sym
*sym_push(int v
, int t
, int r
, int c
);
564 int type_size(int t
, int *a
);
565 int pointed_type(int t
);
566 int pointed_size(int t
);
567 int is_compatible_types(int t1
, int t2
);
568 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
569 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
571 void error(const char *fmt
, ...);
572 void rt_error(unsigned long pc
, const char *fmt
, ...);
574 void vset(int t
, int r
, int v
);
575 void type_to_str(char *buf
, int buf_size
,
576 int t
, const char *varstr
);
577 char *get_tok_str(int v
, CValue
*cv
);
579 /* section generation */
580 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
);
581 void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
582 static int put_elf_str(Section
*s
, const char *sym
);
583 static int put_elf_sym(Section
*s
,
584 unsigned long value
, unsigned long size
,
585 int info
, int other
, int shndx
, const char *name
);
586 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
587 int type
, int symbol
);
588 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
589 static void put_stabn(int type
, int other
, int desc
, int value
);
590 static void put_stabd(int type
, int other
, int desc
);
592 /* true if float/double/long double type */
593 static inline int is_float(int t
)
597 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
600 #ifdef CONFIG_TCC_BCHECK
604 #ifdef TCC_TARGET_I386
605 #include "i386-gen.c"
611 #ifdef CONFIG_TCC_STATIC
613 #define RTLD_LAZY 0x001
614 #define RTLD_NOW 0x002
615 #define RTLD_GLOBAL 0x100
617 /* dummy function for profiling */
618 void *dlopen(const char *filename
, int flag
)
623 const char *dlerror(void)
628 typedef struct TCCSyms
{
633 #define TCCSYM(a) { #a, &a, },
635 /* add the symbol you want here if no dynamic linking is done */
636 static TCCSyms tcc_syms
[] = {
644 void *dlsym(void *handle
, const char *symbol
)
648 while (p
->str
!= NULL
) {
649 if (!strcmp(p
->str
, symbol
))
658 /********************************************************/
659 /* runtime library is there */
660 /* XXX: we suppose that the host compiler handles 'long long'. It
661 would not be difficult to suppress this assumption */
663 long long __divll(long long a
, long long b
)
668 long long __modll(long long a
, long long b
)
673 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
678 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
683 long long __sardi3(long long a
, int b
)
688 unsigned long long __shrdi3(unsigned long long a
, int b
)
693 long long __shldi3(long long a
, int b
)
698 float __ulltof(unsigned long long a
)
703 double __ulltod(unsigned long long a
)
708 long double __ulltold(unsigned long long a
)
710 return (long double)a
;
713 unsigned long long __ftoull(float a
)
715 return (unsigned long long)a
;
718 unsigned long long __dtoull(double a
)
720 return (unsigned long long)a
;
723 unsigned long long __ldtoull(long double a
)
725 return (unsigned long long)a
;
729 /********************************************************/
731 /* we use our own 'finite' function to avoid potential problems with
732 non standard math libs */
733 /* XXX: endianness dependant */
734 int ieee_finite(double d
)
737 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
740 /* copy a string and truncate it. */
741 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
748 q_end
= buf
+ buf_size
- 1;
760 /* strcat and truncate. */
761 char *pstrcat(char *buf
, int buf_size
, const char *s
)
766 pstrcpy(buf
+ len
, buf_size
- len
, s
);
770 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
772 Section
*sec
, **psec
;
775 sec
= malloc(sizeof(Section
));
777 error("memory full");
778 memset(sec
, 0, sizeof(Section
));
779 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
780 sec
->sh_type
= sh_type
;
781 sec
->sh_flags
= sh_flags
;
788 sec
->sh_addralign
= 4;
791 sec
->sh_addralign
= 1;
794 sec
->sh_addralign
= 32; /* default conservative alignment */
798 /* XXX: currently, a single malloc */
799 data
= malloc(SECTION_VSIZE
);
801 error("could not alloc section '%s'", name
);
803 data
= mmap(NULL
, SECTION_VSIZE
,
804 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
805 MAP_PRIVATE
| MAP_ANONYMOUS
,
807 if (data
== (void *)(-1))
808 error("could not mmap section '%s'", name
);
811 sec
->data_ptr
= data
;
813 if (!(sh_flags
& SHF_PRIVATE
)) {
814 /* only add section if not private */
816 psec
= &first_section
;
817 while (*psec
!= NULL
)
818 psec
= &(*psec
)->next
;
822 if ((nb_sections
+ 1) > nb_allocated_sections
) {
823 if (nb_allocated_sections
== 0)
824 nb_allocated_sections
= 1;
825 nb_allocated_sections
*= 2;
826 sections
= realloc(sections
,
827 nb_allocated_sections
* sizeof(Section
*));
829 error("memory full");
831 sections
[nb_sections
] = sec
;
832 sec
->sh_num
= nb_sections
;
838 /* return a reference to a section, and create it if it does not
840 Section
*find_section(const char *name
)
844 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
845 if (!strcmp(name
, sec
->name
))
848 /* sections are created as PROGBITS */
849 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
852 /* add a new relocation entry to symbol 'sym' in section 's' */
853 void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
856 put_extern_sym(sym
, NULL
, 0);
857 /* now we can add ELF relocation info */
858 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
861 static inline int isid(int c
)
863 return (c
>= 'a' && c
<= 'z') ||
864 (c
>= 'A' && c
<= 'Z') ||
868 static inline int isnum(int c
)
870 return c
>= '0' && c
<= '9';
873 static inline int toup(int c
)
875 if (ch
>= 'a' && ch
<= 'z')
876 return ch
- 'a' + 'A';
885 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
886 fprintf(stderr
, "In file included from %s:%d:\n",
887 (*f
)->filename
, (*f
)->line_num
);
888 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
890 fprintf(stderr
, "tcc: ");
894 void error(const char *fmt
, ...)
899 vfprintf(stderr
, fmt
, ap
);
900 fprintf(stderr
, "\n");
905 void expect(const char *msg
)
907 error("%s expected", msg
);
910 void warning(const char *fmt
, ...)
916 fprintf(stderr
, "warning: ");
917 vfprintf(stderr
, fmt
, ap
);
918 fprintf(stderr
, "\n");
925 error("'%c' expected", c
);
929 void test_lvalue(void)
931 if (!(vtop
->r
& VT_LVAL
))
935 TokenSym
*tok_alloc(const char *str
, int len
)
937 TokenSym
*ts
, **pts
, **ptable
;
944 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
946 pts
= &hash_ident
[h
];
951 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
953 pts
= &(ts
->hash_next
);
956 if (tok_ident
>= SYM_FIRST_ANOM
)
957 error("memory full");
959 /* expand token table if needed */
960 i
= tok_ident
- TOK_IDENT
;
961 if ((i
% TOK_ALLOC_INCR
) == 0) {
962 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
964 error("memory full");
965 table_ident
= ptable
;
968 ts
= malloc(sizeof(TokenSym
) + len
);
970 error("memory full");
972 ts
->tok
= tok_ident
++;
974 ts
->hash_next
= NULL
;
975 memcpy(ts
->str
, str
, len
+ 1);
980 void add_char(char **pp
, int c
)
984 if (c
== '\'' || c
== '\"' || c
== '\\') {
985 /* XXX: could be more precise if char or string */
988 if (c
>= 32 && c
<= 126) {
995 *p
++ = '0' + ((c
>> 6) & 7);
996 *p
++ = '0' + ((c
>> 3) & 7);
997 *p
++ = '0' + (c
& 7);
1003 /* XXX: buffer overflow */
1004 char *get_tok_str(int v
, CValue
*cv
)
1006 static char buf
[STRING_MAX_SIZE
+ 1];
1011 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
1012 sprintf(buf
, "%u", cv
->ui
);
1014 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
1017 add_char(&p
, cv
->i
);
1021 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
1025 for(i
=0;i
<ts
->len
;i
++)
1026 add_char(&p
, ts
->str
[i
]);
1030 } else if (v
< TOK_IDENT
) {
1035 } else if (v
< tok_ident
) {
1036 return table_ident
[v
- TOK_IDENT
]->str
;
1037 } else if (v
>= SYM_FIRST_ANOM
) {
1038 /* special name for anonymous symbol */
1039 sprintf(buf
, "L.%u", v
- SYM_FIRST_ANOM
);
1042 /* should never happen */
1047 /* push, without hashing */
1048 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1051 s
= malloc(sizeof(Sym
));
1053 error("memory full");
1064 /* find a symbol and return its associated structure. 's' is the top
1065 of the symbol stack */
1066 Sym
*sym_find2(Sym
*s
, int v
)
1076 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1078 /* find a symbol and return its associated structure. 'st' is the
1080 Sym
*sym_find1(SymStack
*st
, int v
)
1084 s
= st
->hash
[HASH_SYM(v
)];
1093 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1096 s
= sym_push2(&st
->top
, v
, t
, c
);
1097 /* add in hash table */
1099 ps
= &st
->hash
[HASH_SYM(v
)];
1106 /* find a symbol in the right symbol space */
1107 Sym
*sym_find(int v
)
1110 s
= sym_find1(&local_stack
, v
);
1112 s
= sym_find1(&global_stack
, v
);
1116 /* push a given symbol on the symbol stack */
1117 Sym
*sym_push(int v
, int t
, int r
, int c
)
1120 if (local_stack
.top
)
1121 s
= sym_push1(&local_stack
, v
, t
, c
);
1123 s
= sym_push1(&global_stack
, v
, t
, c
);
1128 /* pop symbols until top reaches 'b' */
1129 void sym_pop(SymStack
*st
, Sym
*b
)
1136 /* free hash table entry, except if symbol was freed (only
1137 used for #undef symbols) */
1139 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1146 /* undefined a hashed symbol (used for #undef). Its name is set to
1148 void sym_undef(SymStack
*st
, Sym
*s
)
1151 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1152 while (*ss
!= NULL
) {
1155 ss
= &(*ss
)->hash_next
;
1163 BufferedFile
*tcc_open(const char *filename
)
1168 fd
= open(filename
, O_RDONLY
);
1171 bf
= malloc(sizeof(BufferedFile
));
1177 bf
->buf_ptr
= bf
->buffer
;
1178 bf
->buf_end
= bf
->buffer
;
1179 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1180 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1182 // printf("opening '%s'\n", filename);
1186 void tcc_close(BufferedFile
*bf
)
1188 total_lines
+= bf
->line_num
;
1193 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1194 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1196 /* fill input buffer and return next char */
1197 int tcc_getc_slow(BufferedFile
*bf
)
1200 /* only tries to read if really end of buffer */
1201 if (bf
->buf_ptr
>= bf
->buf_end
) {
1203 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1210 bf
->buf_ptr
= bf
->buffer
;
1211 bf
->buf_end
= bf
->buffer
+ len
;
1212 *bf
->buf_end
= CH_EOB
;
1214 if (bf
->buf_ptr
< bf
->buf_end
) {
1215 return *bf
->buf_ptr
++;
1217 bf
->buf_ptr
= bf
->buf_end
;
1222 /* no need to put that inline */
1223 void handle_eob(void)
1226 ch1
= tcc_getc_slow(file
);
1230 if (include_stack_ptr
== include_stack
)
1232 /* add end of include file debug info */
1234 put_stabd(N_EINCL
, 0, 0);
1236 /* pop include stack */
1238 include_stack_ptr
--;
1239 file
= *include_stack_ptr
;
1243 /* read next char from current input file */
1244 static inline void inp(void)
1246 ch1
= TCC_GETC(file
);
1247 /* end of buffer/file handling */
1252 // printf("ch1=%c 0x%x\n", ch1, ch1);
1255 /* input with '\\n' handling */
1256 static inline void minp(void)
1261 if (ch
== '\\' && ch1
== '\n') {
1265 //printf("ch=%c 0x%x\n", ch, ch);
1269 /* same as minp, but also skip comments */
1277 /* single line C++ comments */
1279 while (ch1
!= '\n' && ch1
!= -1)
1282 ch
= ' '; /* return space */
1283 } else if (ch1
== '*') {
1289 if (c
== '*' && ch1
== '/') {
1291 ch
= ' '; /* return space */
1303 void skip_spaces(void)
1305 while (ch
== ' ' || ch
== '\t')
1309 /* skip block of text until #else, #elif or #endif. skip also pairs of
1311 void preprocess_skip(void)
1316 while (ch
!= '\n') {
1327 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1329 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1331 else if (tok
== TOK_ENDIF
)
1337 /* ParseState handling */
1339 /* XXX: currently, no include file info is stored. Thus, we cannot display
1340 accurate messages if the function or data definition spans multiple
1343 /* save current parse state in 's' */
1344 void save_parse_state(ParseState
*s
)
1346 s
->line_num
= file
->line_num
;
1347 s
->macro_ptr
= macro_ptr
;
1352 /* restore parse state from 's' */
1353 void restore_parse_state(ParseState
*s
)
1355 file
->line_num
= s
->line_num
;
1356 macro_ptr
= s
->macro_ptr
;
1361 /* return the number of additionnal 'ints' necessary to store the
1363 static inline int tok_ext_size(int t
)
1381 return LDOUBLE_SIZE
/ 4;
1387 /* token string handling */
1389 static inline void tok_str_new(TokenString
*s
)
1393 s
->last_line_num
= -1;
1396 static void tok_str_add(TokenString
*s
, int t
)
1402 if ((len
& 63) == 0) {
1403 str
= realloc(str
, (len
+ 64) * sizeof(int));
1412 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1416 n
= tok_ext_size(t
);
1418 tok_str_add(s
, cv
->tab
[i
]);
1421 /* add the current parse token in token string 's' */
1422 static void tok_str_add_tok(TokenString
*s
)
1426 /* save line number info */
1427 if (file
->line_num
!= s
->last_line_num
) {
1428 s
->last_line_num
= file
->line_num
;
1429 cval
.i
= s
->last_line_num
;
1430 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1432 tok_str_add2(s
, tok
, &tokc
);
1435 /* get a token from an integer array and increment pointer accordingly */
1436 static int tok_get(int **tok_str
, CValue
*cv
)
1442 n
= tok_ext_size(t
);
1449 /* eval an expression for #if/#elif */
1450 int expr_preprocess(void)
1460 next(); /* do macro subst */
1461 if (tok
== TOK_DEFINED
) {
1466 c
= sym_find1(&define_stack
, tok
) != 0;
1471 } else if (tok
>= TOK_IDENT
) {
1472 /* if undefined macro */
1476 tok_str_add_tok(&str
);
1478 tok_str_add(&str
, -1); /* simulate end of file */
1479 tok_str_add(&str
, 0);
1480 /* now evaluate C constant expression */
1481 macro_ptr
= str
.str
;
1489 #if defined(DEBUG) || defined(PP_DEBUG)
1490 void tok_print(int *str
)
1496 t
= tok_get(&str
, &cval
);
1499 printf(" %s", get_tok_str(t
, &cval
));
1505 /* parse after #define */
1506 void parse_define(void)
1508 Sym
*s
, *first
, **ps
;
1509 int v
, t
, varg
, is_vaargs
;
1513 /* XXX: should check if same macro (ANSI) */
1516 /* '(' must be just after macro definition for MACRO_FUNC */
1521 while (tok
!= ')') {
1525 if (varg
== TOK_DOTS
) {
1526 varg
= TOK___VA_ARGS__
;
1528 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1532 if (varg
< TOK_IDENT
)
1533 error("badly punctuated parameter list");
1534 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1546 if (ch
== '\n' || ch
== -1)
1549 tok_str_add2(&str
, tok
, &tokc
);
1551 tok_str_add(&str
, 0);
1553 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1556 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1560 void preprocess(void)
1563 char buf
[1024], *q
, *p
;
1571 if (tok
== TOK_DEFINE
) {
1574 } else if (tok
== TOK_UNDEF
) {
1576 s
= sym_find1(&define_stack
, tok
);
1577 /* undefine symbol by putting an invalid name */
1579 sym_undef(&define_stack
, s
);
1580 } else if (tok
== TOK_INCLUDE
) {
1585 } else if (ch
== '\"') {
1590 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1591 if ((q
- buf
) < sizeof(buf
) - 1)
1599 error("#include syntax error");
1600 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1603 /* eat all spaces and comments after include */
1604 /* XXX: slightly incorrect */
1605 while (ch1
!= '\n' && ch1
!= -1)
1608 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1609 error("memory full");
1611 /* first search in current dir if "header.h" */
1613 p
= strrchr(file
->filename
, '/');
1615 size
= p
+ 1 - file
->filename
;
1616 if (size
> sizeof(buf1
) - 1)
1617 size
= sizeof(buf1
) - 1;
1618 memcpy(buf1
, file
->filename
, size
);
1620 pstrcat(buf1
, sizeof(buf1
), buf
);
1625 /* now search in standard include path */
1626 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1627 strcpy(buf1
, include_paths
[i
]);
1634 error("include file '%s' not found", buf
);
1637 /* push current file in stack */
1638 /* XXX: fix current line init */
1639 *include_stack_ptr
++ = file
;
1641 /* add include file debug info */
1643 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1645 } else if (tok
== TOK_IFNDEF
) {
1648 } else if (tok
== TOK_IF
) {
1649 c
= expr_preprocess();
1651 } else if (tok
== TOK_IFDEF
) {
1655 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1657 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1658 error("memory full");
1659 *ifdef_stack_ptr
++ = c
;
1661 } else if (tok
== TOK_ELSE
) {
1662 if (ifdef_stack_ptr
== ifdef_stack
)
1663 error("#else without matching #if");
1664 if (ifdef_stack_ptr
[-1] & 2)
1665 error("#else after #else");
1666 c
= (ifdef_stack_ptr
[-1] ^= 3);
1668 } else if (tok
== TOK_ELIF
) {
1669 if (ifdef_stack_ptr
== ifdef_stack
)
1670 error("#elif without matching #if");
1671 c
= ifdef_stack_ptr
[-1];
1673 error("#elif after #else");
1674 /* last #if/#elif expression was true: we skip */
1677 c
= expr_preprocess();
1678 ifdef_stack_ptr
[-1] = c
;
1685 } else if (tok
== TOK_ENDIF
) {
1686 if (ifdef_stack_ptr
== ifdef_stack
)
1687 error("#endif without matching #if");
1689 } else if (tok
== TOK_LINE
) {
1691 if (tok
!= TOK_CINT
)
1693 file
->line_num
= tokc
.i
;
1699 pstrcpy(file
->filename
, sizeof(file
->filename
),
1700 get_tok_str(tok
, &tokc
));
1702 } else if (tok
== TOK_ERROR
) {
1705 /* ignore other preprocess commands or #! for C scripts */
1706 while (ch
!= '\n' && ch
!= -1)
1710 /* read a number in base b */
1716 if (ch
>= 'a' && ch
<= 'f')
1718 else if (ch
>= 'A' && ch
<= 'F')
1724 if (t
< 0 || t
>= b
)
1732 /* read a character for string or char constant and eval escape codes */
1741 /* at most three octal digits */
1745 c
= c
* 8 + ch
- '0';
1748 c
= c
* 8 + ch
- '0';
1753 } else if (ch
== 'x') {
1771 else if (ch
== 'e' && gnu_ext
)
1773 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1776 error("invalid escaped char");
1783 /* we use 64 bit numbers */
1786 /* bn = (bn << shift) | or_val */
1787 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1791 for(i
=0;i
<BN_SIZE
;i
++) {
1793 bn
[i
] = (v
<< shift
) | or_val
;
1794 or_val
= v
>> (32 - shift
);
1798 void bn_zero(unsigned int *bn
)
1801 for(i
=0;i
<BN_SIZE
;i
++) {
1806 void parse_number(void)
1808 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1810 unsigned int bn
[BN_SIZE
];
1820 /* special dot handling */
1821 if (ch
>= '0' && ch
<= '9') {
1822 goto float_frac_parse
;
1823 } else if (ch
== '.') {
1834 } else if (t
== '0') {
1835 if (ch
== 'x' || ch
== 'X') {
1839 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1845 /* parse all digits. cannot check octal numbers at this stage
1846 because of floating point constants */
1848 if (ch
>= 'a' && ch
<= 'f')
1850 else if (ch
>= 'A' && ch
<= 'F')
1858 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1860 error("number too long");
1866 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1867 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1869 /* NOTE: strtox should support that for hexa numbers, but
1870 non ISOC99 libcs do not support it, so we prefer to do
1872 /* hexadecimal or binary floats */
1873 /* XXX: handle overflows */
1885 } else if (t
>= 'a') {
1887 } else if (t
>= 'A') {
1892 bn_lshift(bn
, shift
, t
);
1899 if (t
>= 'a' && t
<= 'f') {
1901 } else if (t
>= 'A' && t
<= 'F') {
1903 } else if (t
>= '0' && t
<= '9') {
1909 error("invalid digit");
1910 bn_lshift(bn
, shift
, t
);
1915 if (ch
!= 'p' && ch
!= 'P')
1916 error("exponent expected");
1922 } else if (ch
== '-') {
1926 if (ch
< '0' || ch
> '9')
1927 error("exponent digits expected");
1928 while (ch
>= '0' && ch
<= '9') {
1929 exp_val
= exp_val
* 10 + ch
- '0';
1932 exp_val
= exp_val
* s
;
1934 /* now we can generate the number */
1935 /* XXX: should patch directly float number */
1936 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1937 d
= ldexp(d
, exp_val
- frac_bits
);
1942 /* float : should handle overflow */
1944 } else if (t
== 'L') {
1947 /* XXX: not large enough */
1948 tokc
.ld
= (long double)d
;
1954 /* decimal floats */
1956 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1961 while (ch
>= '0' && ch
<= '9') {
1962 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1968 if (ch
== 'e' || ch
== 'E') {
1969 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1973 if (ch
== '-' || ch
== '+') {
1974 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1979 if (ch
< '0' || ch
> '9')
1980 error("exponent digits expected");
1981 while (ch
>= '0' && ch
<= '9') {
1982 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1994 tokc
.f
= strtof(token_buf
, NULL
);
1995 } else if (t
== 'L') {
1998 tokc
.ld
= strtold(token_buf
, NULL
);
2001 tokc
.d
= strtod(token_buf
, NULL
);
2005 unsigned long long n
, n1
;
2008 /* integer number */
2011 if (b
== 10 && *q
== '0') {
2018 /* no need for checks except for base 10 / 8 errors */
2021 } else if (t
>= 'a') {
2023 } else if (t
>= 'A') {
2028 error("invalid digit");
2032 /* detect overflow */
2034 error("integer constant overflow");
2037 /* XXX: not exactly ANSI compliant */
2038 if ((n
& 0xffffffff00000000LL
) != 0) {
2043 } else if (n
> 0x7fffffff) {
2053 error("three 'l' in integer constant");
2056 if (tok
== TOK_CINT
)
2058 else if (tok
== TOK_CUINT
)
2062 } else if (t
== 'U') {
2063 if (tok
== TOK_CINT
)
2065 else if (tok
== TOK_CLLONG
)
2072 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2080 /* return next token without macro substitution */
2081 void next_nomacro1(void)
2089 while (ch
== '\n') {
2091 while (ch
== ' ' || ch
== '\t')
2094 /* preprocessor command if # at start of line after
2099 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2117 while (isid(ch
) || isnum(ch
)) {
2118 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2119 error("ident too long");
2124 ts
= tok_alloc(token_buf
, q
- token_buf
);
2126 } else if (isnum(ch
) || ch
== '.') {
2128 } else if (ch
== '\'') {
2136 } else if (ch
== '\"') {
2141 while (ch
!= '\"') {
2144 error("unterminated string");
2145 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2146 error("string too long");
2150 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2153 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2158 if (*q
== tok
&& q
[1] == ch
) {
2161 /* three chars tests */
2162 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2167 } else if (tok
== TOK_DOTS
) {
2169 error("parse error");
2176 /* single char substitutions */
2179 else if (tok
== '>')
2184 /* return next token without macro substitution. Can read input from
2192 tok
= tok_get(¯o_ptr
, &tokc
);
2193 if (tok
== TOK_LINENUM
) {
2194 file
->line_num
= tokc
.i
;
2203 /* substitute args in macro_str and return allocated string */
2204 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2206 int *st
, last_tok
, t
, notfirst
;
2215 t
= tok_get(¯o_str
, &cval
);
2220 t
= tok_get(¯o_str
, &cval
);
2223 s
= sym_find2(args
, t
);
2225 token_buf
[0] = '\0';
2230 pstrcat(token_buf
, sizeof(token_buf
), " ");
2231 t
= tok_get(&st
, &cval
);
2232 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2236 printf("stringize: %s\n", token_buf
);
2239 ts
= tok_alloc(token_buf
, 0);
2241 tok_str_add2(&str
, TOK_STR
, &cval
);
2243 tok_str_add2(&str
, t
, &cval
);
2245 } else if (t
>= TOK_IDENT
) {
2246 s
= sym_find2(args
, t
);
2249 /* if '##' is present before or after, no arg substitution */
2250 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2251 /* special case for var arg macros : ## eats the
2252 ',' if empty VA_ARGS riable. */
2253 /* XXX: test of the ',' is not 100%
2254 reliable. should fix it to avoid security
2256 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2257 last_tok
== TOK_TWOSHARPS
&&
2258 str
.len
>= 2&& str
.str
[str
.len
- 2] == ',') {
2259 /* suppress ',' '##' */
2263 tok_str_add(&str
, *st
++);
2266 macro_subst(&str
, nested_list
, st
);
2269 tok_str_add(&str
, t
);
2272 tok_str_add2(&str
, t
, &cval
);
2276 tok_str_add(&str
, 0);
2280 /* handle the '##' operator */
2281 int *macro_twosharps(int *macro_str
)
2288 TokenString macro_str1
;
2290 tok_str_new(¯o_str1
);
2296 while (*macro_ptr
== TOK_TWOSHARPS
) {
2298 macro_ptr1
= macro_ptr
;
2301 t
= tok_get(¯o_ptr
, &cval
);
2302 /* XXX: we handle only most common cases:
2303 ident + ident or ident + number */
2304 if (tok
>= TOK_IDENT
&&
2305 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2306 p
= get_tok_str(tok
, &tokc
);
2307 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2308 p
= get_tok_str(t
, &cval
);
2309 pstrcat(token_buf
, sizeof(token_buf
), p
);
2310 ts
= tok_alloc(token_buf
, 0);
2311 tok
= ts
->tok
; /* modify current token */
2313 /* cannot merge tokens: skip '##' */
2314 macro_ptr
= macro_ptr1
;
2319 tok_str_add2(¯o_str1
, tok
, &tokc
);
2321 tok_str_add(¯o_str1
, 0);
2322 return macro_str1
.str
;
2325 /* do macro substitution of macro_str and add result to
2326 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2327 substituted. 'nested_list' is the list of all macros we got inside
2328 to avoid recursing. */
2329 void macro_subst(TokenString
*tok_str
,
2330 Sym
**nested_list
, int *macro_str
)
2332 Sym
*s
, *args
, *sa
, *sa1
;
2333 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2334 int mstr_allocated
, *macro_str1
;
2338 saved_macro_ptr
= macro_ptr
;
2339 macro_ptr
= macro_str
;
2342 /* first scan for '##' operator handling */
2343 macro_str1
= macro_twosharps(macro_str
);
2344 macro_ptr
= macro_str1
;
2351 /* special macros */
2352 if (tok
== TOK___LINE__
) {
2353 cval
.i
= file
->line_num
;
2354 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2355 } else if (tok
== TOK___FILE__
) {
2356 cval
.ts
= tok_alloc(file
->filename
, 0);
2357 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2358 } else if (tok
== TOK___DATE__
) {
2359 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2360 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2361 } else if (tok
== TOK___TIME__
) {
2362 cval
.ts
= tok_alloc("00:00:00", 0);
2363 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2364 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2365 /* if symbol is a macro, prepare substitution */
2366 /* if nested substitution, do nothing */
2367 if (sym_find2(*nested_list
, tok
))
2371 if (s
->t
== MACRO_FUNC
) {
2372 /* NOTE: we do not use next_nomacro to avoid eating the
2373 next token. XXX: find better solution */
2377 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2381 if (t
!= '(') /* no macro subst */
2384 /* argument macro */
2389 /* NOTE: empty args are allowed, except if no args */
2391 /* handle '()' case */
2392 if (!args
&& tok
== ')')
2395 error("macro '%s' used with too many args",
2396 get_tok_str(s
->v
, 0));
2399 /* NOTE: non zero sa->t indicates VA_ARGS */
2400 while ((parlevel
> 0 ||
2402 (tok
!= ',' || sa
->t
))) &&
2406 else if (tok
== ')')
2408 tok_str_add2(&str
, tok
, &tokc
);
2411 tok_str_add(&str
, 0);
2412 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2415 /* special case for gcc var args: add an empty
2416 var arg argument if it is omitted */
2417 if (sa
&& sa
->t
&& gnu_ext
)
2427 error("macro '%s' used with too few args",
2428 get_tok_str(s
->v
, 0));
2431 /* now subst each arg */
2432 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2443 sym_push2(nested_list
, s
->v
, 0, 0);
2444 macro_subst(tok_str
, nested_list
, mstr
);
2445 /* pop nested defined symbol */
2447 *nested_list
= sa1
->prev
;
2453 /* no need to add if reading input stream */
2456 tok_str_add2(tok_str
, tok
, &tokc
);
2458 /* only replace one macro while parsing input stream */
2462 macro_ptr
= saved_macro_ptr
;
2467 /* return next token with macro substitution */
2473 /* special 'ungettok' case for label parsing */
2481 /* if not reading from macro substituted string, then try
2483 /* XXX: optimize non macro case */
2486 macro_subst(&str
, &nested_list
, NULL
);
2488 tok_str_add(&str
, 0);
2489 macro_ptr
= str
.str
;
2490 macro_ptr_allocated
= str
.str
;
2498 /* end of macro string: free it */
2499 free(macro_ptr_allocated
);
2506 printf("token = %s\n", get_tok_str(tok
, tokc
));
2510 void swap(int *p
, int *q
)
2518 void vsetc(int t
, int r
, CValue
*vc
)
2520 if (vtop
>= vstack
+ VSTACK_SIZE
)
2521 error("memory full");
2522 /* cannot let cpu flags if other instruction are generated */
2523 /* XXX: VT_JMP test too ? */
2524 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2529 vtop
->r2
= VT_CONST
;
2533 /* push integer constant */
2538 vsetc(VT_INT
, VT_CONST
, &cval
);
2541 /* push a reference to a section offset by adding a dummy symbol */
2542 void vpush_ref(int t
, Section
*sec
, unsigned long offset
)
2549 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2550 sym
->r
= VT_CONST
| VT_SYM
;
2551 put_extern_sym(sym
, sec
, offset
);
2553 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2556 void vset(int t
, int r
, int v
)
2573 void vpushv(SValue
*v
)
2575 if (vtop
>= vstack
+ VSTACK_SIZE
)
2576 error("memory full");
2586 /* save r to the memory stack, and mark it as being free */
2587 void save_reg(int r
)
2589 int l
, i
, saved
, t
, size
, align
;
2592 /* modify all stack values */
2595 for(p
=vstack
;p
<=vtop
;p
++) {
2596 i
= p
->r
& VT_VALMASK
;
2597 if ((p
->r
& VT_VALMASK
) == r
||
2598 (p
->r2
& VT_VALMASK
) == r
) {
2599 /* must save value on stack if not already done */
2601 /* store register in the stack */
2603 if ((p
->r
& VT_LVAL
) ||
2604 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2606 size
= type_size(t
, &align
);
2607 loc
= (loc
- size
) & -align
;
2609 sv
.r
= VT_LOCAL
| VT_LVAL
;
2612 #ifdef TCC_TARGET_I386
2613 /* x86 specific: need to pop fp register ST0 if saved */
2615 o(0xd9dd); /* fstp %st(1) */
2618 /* special long long case */
2619 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2626 /* mark that stack entry as being saved on the stack */
2638 /* find a free register of class 'rc'. If none, save one register */
2644 /* find a free register */
2645 for(r
=0;r
<NB_REGS
;r
++) {
2646 if (reg_classes
[r
] & rc
) {
2647 for(p
=vstack
;p
<=vtop
;p
++) {
2648 if ((p
->r
& VT_VALMASK
) == r
||
2649 (p
->r2
& VT_VALMASK
) == r
)
2657 /* no register left : free the first one on the stack (VERY
2658 IMPORTANT to start from the bottom to ensure that we don't
2659 spill registers used in gen_opi()) */
2660 for(p
=vstack
;p
<=vtop
;p
++) {
2661 r
= p
->r
& VT_VALMASK
;
2662 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2670 /* save registers up to (vtop - n) stack entry */
2671 void save_regs(int n
)
2676 for(p
= vstack
;p
<= p1
; p
++) {
2677 r
= p
->r
& VT_VALMASK
;
2684 /* move register 's' to 'r', and flush previous value of r to memory
2686 void move_reg(int r
, int s
)
2699 /* get address of vtop (vtop MUST BE an lvalue) */
2702 vtop
->r
&= ~VT_LVAL
;
2703 /* tricky: if saved lvalue, then we can go back to lvalue */
2704 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2705 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2708 #ifdef CONFIG_TCC_BCHECK
2709 /* generate lvalue bound code */
2714 vtop
->r
&= ~VT_MUSTBOUND
;
2715 /* if lvalue, then use checking code before dereferencing */
2716 if (vtop
->r
& VT_LVAL
) {
2717 /* if not VT_BOUNDED value, then make one */
2718 if (!(vtop
->r
& VT_BOUNDED
)) {
2719 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2722 gen_bounded_ptr_add();
2723 vtop
->r
|= lval_type
;
2725 /* then check for dereferencing */
2726 gen_bounded_ptr_deref();
2731 /* store vtop a register belonging to class 'rc'. lvalues are
2732 converted to values. Cannot be used if cannot be converted to
2733 register value (such as structures). */
2736 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2737 unsigned long long ll
;
2739 /* NOTE: get_reg can modify vstack[] */
2740 if (vtop
->t
& VT_BITFIELD
) {
2741 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2742 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2743 /* remove bit field info to avoid loops */
2744 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2745 /* generate shifts */
2746 vpushi(32 - (bit_pos
+ bit_size
));
2748 vpushi(32 - bit_size
);
2749 /* NOTE: transformed to SHR if unsigned */
2753 if (is_float(vtop
->t
) &&
2754 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2758 /* XXX: unify with initializers handling ? */
2759 /* CPUs usually cannot use float constants, so we store them
2760 generically in data segment */
2761 size
= type_size(vtop
->t
, &align
);
2762 data_offset
= data_section
->data_ptr
- data_section
->data
;
2763 data_offset
= (data_offset
+ align
- 1) & -align
;
2764 /* XXX: not portable yet */
2767 ((int *)(data_section
->data
+ data_offset
))[i
] = vtop
->c
.tab
[i
];
2770 sym
= sym_push1(&global_stack
, v
, vtop
->t
| VT_STATIC
, 0);
2771 sym
->r
= VT_CONST
| VT_SYM
;
2772 put_extern_sym(sym
, data_section
, data_offset
);
2774 vtop
->r
|= VT_LVAL
| VT_SYM
;
2776 data_offset
+= size
<< 2;
2777 data_section
->data_ptr
= data_section
->data
+ data_offset
;
2779 #ifdef CONFIG_TCC_BCHECK
2780 if (vtop
->r
& VT_MUSTBOUND
)
2784 r
= vtop
->r
& VT_VALMASK
;
2785 /* need to reload if:
2787 - lvalue (need to dereference pointer)
2788 - already a register, but not in the right class */
2789 if (r
>= VT_CONST
||
2790 (vtop
->r
& VT_LVAL
) ||
2791 !(reg_classes
[r
] & rc
) ||
2792 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2793 !(reg_classes
[vtop
->r2
] & rc
))) {
2795 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2796 /* two register type load : expand to two words
2798 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2801 vtop
->c
.ui
= ll
; /* first word */
2803 vtop
->r
= r
; /* save register value */
2804 vpushi(ll
>> 32); /* second word */
2805 } else if (r
>= VT_CONST
||
2806 (vtop
->r
& VT_LVAL
)) {
2807 /* load from memory */
2810 vtop
[-1].r
= r
; /* save register value */
2811 /* increment pointer to get second word */
2818 /* move registers */
2821 vtop
[-1].r
= r
; /* save register value */
2822 vtop
->r
= vtop
[-1].r2
;
2824 /* allocate second register */
2831 /* write second register */
2833 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2835 /* lvalue of scalar type : need to use lvalue type
2836 because of possible cast */
2839 /* compute memory access type */
2840 if (vtop
->r
& VT_LVAL_BYTE
)
2842 else if (vtop
->r
& VT_LVAL_SHORT
)
2844 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2848 /* restore wanted type */
2851 /* one register type load */
2860 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2861 void gv2(int rc1
, int rc2
)
2863 /* generate more generic register first */
2869 /* test if reload is needed for first register */
2870 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2880 /* test if reload is needed for first register */
2881 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2887 /* expand long long on stack in two int registers */
2892 u
= vtop
->t
& VT_UNSIGNED
;
2895 vtop
[0].r
= vtop
[-1].r2
;
2896 vtop
[0].r2
= VT_CONST
;
2897 vtop
[-1].r2
= VT_CONST
;
2898 vtop
[0].t
= VT_INT
| u
;
2899 vtop
[-1].t
= VT_INT
| u
;
2902 /* build a long long from two ints */
2905 gv2(RC_INT
, RC_INT
);
2906 vtop
[-1].r2
= vtop
[0].r
;
2911 /* rotate n first stack elements to the bottom */
2918 for(i
=-n
+1;i
!=0;i
++)
2919 vtop
[i
] = vtop
[i
+1];
2923 /* pop stack value */
2927 v
= vtop
->r
& VT_VALMASK
;
2928 #ifdef TCC_TARGET_I386
2929 /* for x86, we need to pop the FP stack */
2931 o(0xd9dd); /* fstp %st(1) */
2934 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2935 /* need to put correct jump if && or || without test */
2941 /* convert stack entry to register and duplicate its value in another
2949 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2956 /* stack: H L L1 H1 */
2964 /* duplicate value */
2975 load(r1
, &sv
); /* move r to r1 */
2977 /* duplicates value */
2982 /* generate CPU independent (unsigned) long long operations */
2983 void gen_opl(int op
)
2985 int t
, a
, b
, op1
, c
, i
;
3004 /* call generic long long function */
3005 gfunc_start(&gf
, FUNC_CDECL
);
3012 vtop
->r2
= REG_LRET
;
3025 /* stack: L1 H1 L2 H2 */
3030 vtop
[-2] = vtop
[-3];
3033 /* stack: H1 H2 L1 L2 */
3039 /* stack: H1 H2 L1 L2 ML MH */
3042 /* stack: ML MH H1 H2 L1 L2 */
3046 /* stack: ML MH H1 L2 H2 L1 */
3051 /* stack: ML MH M1 M2 */
3054 } else if (op
== '+' || op
== '-') {
3055 /* XXX: add non carry method too (for MIPS or alpha) */
3061 /* stack: H1 H2 (L1 op L2) */
3064 gen_op(op1
+ 1); /* TOK_xxxC2 */
3067 /* stack: H1 H2 (L1 op L2) */
3070 /* stack: (L1 op L2) H1 H2 */
3072 /* stack: (L1 op L2) (H1 op H2) */
3080 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3085 /* stack: L H shift */
3087 /* constant: simpler */
3088 /* NOTE: all comments are for SHL. the other cases are
3089 done by swaping words */
3100 if (op
!= TOK_SAR
) {
3130 /* XXX: should provide a faster fallback on x86 ? */
3145 /* compare operations */
3151 /* stack: L1 H1 L2 H2 */
3153 vtop
[-1] = vtop
[-2];
3155 /* stack: L1 L2 H1 H2 */
3158 /* when values are equal, we need to compare low words. since
3159 the jump is inverted, we invert the test too. */
3162 else if (op1
== TOK_GT
)
3164 else if (op1
== TOK_ULT
)
3166 else if (op1
== TOK_UGT
)
3171 if (op1
!= TOK_NE
) {
3175 /* generate non equal test */
3176 /* XXX: NOT PORTABLE yet */
3180 #ifdef TCC_TARGET_I386
3181 b
= psym(0x850f, 0);
3183 error("not implemented");
3191 vset(VT_INT
, VT_JMPI
, a
);
3196 /* handle integer constant optimizations and various machine
3198 void gen_opic(int op
)
3205 /* currently, we cannot do computations with forward symbols */
3206 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3207 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3211 case '+': v1
->c
.i
+= fc
; break;
3212 case '-': v1
->c
.i
-= fc
; break;
3213 case '&': v1
->c
.i
&= fc
; break;
3214 case '^': v1
->c
.i
^= fc
; break;
3215 case '|': v1
->c
.i
|= fc
; break;
3216 case '*': v1
->c
.i
*= fc
; break;
3223 /* if division by zero, generate explicit division */
3226 error("division by zero in constant");
3230 default: v1
->c
.i
/= fc
; break;
3231 case '%': v1
->c
.i
%= fc
; break;
3232 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3233 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3236 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3237 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3238 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3240 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3241 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3242 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3243 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3244 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3245 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3246 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3247 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3248 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3249 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3251 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3252 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3258 /* if commutative ops, put c2 as constant */
3259 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3260 op
== '|' || op
== '*')) {
3265 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3268 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3269 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3275 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3276 /* try to use shifts instead of muls or divs */
3277 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3286 else if (op
== TOK_PDIV
)
3294 /* call low level op generator */
3300 /* generate a floating point operation with constant propagation */
3301 void gen_opif(int op
)
3309 /* currently, we cannot do computations with forward symbols */
3310 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3311 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3313 if (v1
->t
== VT_FLOAT
) {
3316 } else if (v1
->t
== VT_DOUBLE
) {
3324 /* NOTE: we only do constant propagation if finite number (not
3325 NaN or infinity) (ANSI spec) */
3326 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3330 case '+': f1
+= f2
; break;
3331 case '-': f1
-= f2
; break;
3332 case '*': f1
*= f2
; break;
3336 error("division by zero in constant");
3341 /* XXX: also handles tests ? */
3345 /* XXX: overflow test ? */
3346 if (v1
->t
== VT_FLOAT
) {
3348 } else if (v1
->t
== VT_DOUBLE
) {
3361 int pointed_size(int t
)
3363 return type_size(pointed_type(t
), &t
);
3367 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3369 char buf1
[256], buf2
[256];
3373 if (!is_compatible_types(t1
, t2
)) {
3374 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3375 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3376 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3381 /* generic gen_op: handles types problems */
3384 int u
, t1
, t2
, bt1
, bt2
, t
;
3388 bt1
= t1
& VT_BTYPE
;
3389 bt2
= t2
& VT_BTYPE
;
3391 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3392 /* at least one operand is a pointer */
3393 /* relationnal op: must be both pointers */
3394 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3395 // check_pointer_types(vtop, vtop - 1);
3396 /* pointers are handled are unsigned */
3397 t
= VT_INT
| VT_UNSIGNED
;
3400 /* if both pointers, then it must be the '-' op */
3401 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3402 (t2
& VT_BTYPE
) == VT_PTR
) {
3404 error("cannot use pointers here");
3405 // check_pointer_types(vtop - 1, vtop);
3406 /* XXX: check that types are compatible */
3407 u
= pointed_size(t1
);
3409 /* set to integer type */
3414 /* exactly one pointer : must be '+' or '-'. */
3415 if (op
!= '-' && op
!= '+')
3416 error("cannot use pointers here");
3417 /* Put pointer as first operand */
3418 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3422 /* XXX: cast to int ? (long long case) */
3423 vpushi(pointed_size(vtop
[-1].t
));
3425 #ifdef CONFIG_TCC_BCHECK
3426 /* if evaluating constant expression, no code should be
3427 generated, so no bound check */
3428 if (do_bounds_check
&& !const_wanted
) {
3429 /* if bounded pointers, we generate a special code to
3436 gen_bounded_ptr_add();
3442 /* put again type if gen_opic() swaped operands */
3445 } else if (is_float(bt1
) || is_float(bt2
)) {
3446 /* compute bigger type and do implicit casts */
3447 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3449 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3454 /* floats can only be used for a few operations */
3455 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3456 (op
< TOK_ULT
|| op
> TOK_GT
))
3457 error("invalid operands for binary operation");
3459 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3460 /* cast to biggest op */
3462 /* convert to unsigned if it does not fit in a long long */
3463 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3464 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3468 /* integer operations */
3470 /* convert to unsigned if it does not fit in an integer */
3471 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3472 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3475 /* XXX: currently, some unsigned operations are explicit, so
3476 we modify them here */
3477 if (t
& VT_UNSIGNED
) {
3484 else if (op
== TOK_LT
)
3486 else if (op
== TOK_GT
)
3488 else if (op
== TOK_LE
)
3490 else if (op
== TOK_GE
)
3496 /* special case for shifts and long long: we keep the shift as
3498 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3504 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3508 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3509 /* relationnal op: the result is an int */
3517 /* generic itof for unsigned long long case */
3518 void gen_cvt_itof1(int t
)
3522 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3523 (VT_LLONG
| VT_UNSIGNED
)) {
3525 gfunc_start(&gf
, FUNC_CDECL
);
3528 vpushi((int)&__ulltof
);
3529 else if (t
== VT_DOUBLE
)
3530 vpushi((int)&__ulltod
);
3532 vpushi((int)&__ulltold
);
3541 /* generic ftoi for unsigned long long case */
3542 void gen_cvt_ftoi1(int t
)
3547 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3548 /* not handled natively */
3549 gfunc_start(&gf
, FUNC_CDECL
);
3550 st
= vtop
->t
& VT_BTYPE
;
3553 vpushi((int)&__ftoull
);
3554 else if (st
== VT_DOUBLE
)
3555 vpushi((int)&__dtoull
);
3557 vpushi((int)&__ldtoull
);
3561 vtop
->r2
= REG_LRET
;
3567 /* force char or short cast */
3568 void force_charshort_cast(int t
)
3572 /* XXX: add optimization if lvalue : just change type and offset */
3577 if (t
& VT_UNSIGNED
) {
3578 vpushi((1 << bits
) - 1);
3589 /* cast 'vtop' to 't' type */
3590 void gen_cast(int t
)
3592 int sbt
, dbt
, sf
, df
, c
;
3594 /* special delayed cast for char/short */
3595 /* XXX: in some cases (multiple cascaded casts), it may still
3597 if (vtop
->r
& VT_MUSTCAST
) {
3598 vtop
->r
&= ~VT_MUSTCAST
;
3599 force_charshort_cast(vtop
->t
);
3602 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3603 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3608 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3610 /* convert from fp to fp */
3612 /* constant case: we can do it now */
3613 /* XXX: in ISOC, cannot do it if error in convert */
3614 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3615 vtop
->c
.f
= (float)vtop
->c
.d
;
3616 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3617 vtop
->c
.f
= (float)vtop
->c
.ld
;
3618 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3619 vtop
->c
.d
= (double)vtop
->c
.f
;
3620 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3621 vtop
->c
.d
= (double)vtop
->c
.ld
;
3622 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3623 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3624 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3625 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3627 /* non constant case: generate code */
3631 /* convert int to fp */
3634 case VT_LLONG
| VT_UNSIGNED
:
3636 /* XXX: add const cases for long long */
3638 case VT_INT
| VT_UNSIGNED
:
3640 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3641 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3642 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3647 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3648 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3649 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3658 /* convert fp to int */
3659 /* we handle char/short/etc... with generic code */
3660 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3661 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3666 case VT_LLONG
| VT_UNSIGNED
:
3668 /* XXX: add const cases for long long */
3670 case VT_INT
| VT_UNSIGNED
:
3672 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3673 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3674 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3680 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3681 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3682 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3690 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3691 /* additionnal cast for char/short/bool... */
3695 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3696 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3697 /* scalar to long long */
3699 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3700 vtop
->c
.ll
= vtop
->c
.ui
;
3702 vtop
->c
.ll
= vtop
->c
.i
;
3704 /* machine independant conversion */
3706 /* generate high word */
3707 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3715 /* patch second register */
3716 vtop
[-1].r2
= vtop
->r
;
3720 } else if (dbt
== VT_BOOL
) {
3721 /* scalar to bool */
3724 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3725 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3726 force_charshort_cast(t
);
3727 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3729 if (sbt
== VT_LLONG
) {
3730 /* from long long: just take low order word */
3734 /* if lvalue and single word type, nothing to do because
3735 the lvalue already contains the real type size (see
3736 VT_LVAL_xxx constants) */
3742 /* return type size. Put alignment at 'a' */
3743 int type_size(int t
, int *a
)
3749 if (bt
== VT_STRUCT
) {
3751 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3752 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3754 } else if (bt
== VT_PTR
) {
3756 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3757 return type_size(s
->t
, a
) * s
->c
;
3762 } else if (bt
== VT_LDOUBLE
) {
3764 return LDOUBLE_SIZE
;
3765 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3768 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3771 } else if (bt
== VT_SHORT
) {
3775 /* char, void, function, _Bool */
3781 /* return the pointed type of t */
3782 int pointed_type(int t
)
3785 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3786 return s
->t
| (t
& ~VT_TYPE
);
3789 int mk_pointer(int t
)
3793 sym_push(p
, t
, 0, -1);
3794 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3797 int is_compatible_types(int t1
, int t2
)
3804 bt1
= t1
& VT_BTYPE
;
3805 bt2
= t2
& VT_BTYPE
;
3806 if (bt1
== VT_PTR
) {
3807 t1
= pointed_type(t1
);
3808 /* if function, then convert implicitely to function pointer */
3809 if (bt2
!= VT_FUNC
) {
3812 t2
= pointed_type(t2
);
3814 /* void matches everything */
3817 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3819 return is_compatible_types(t1
, t2
);
3820 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3822 } else if (bt1
== VT_FUNC
) {
3825 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3826 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3827 if (!is_compatible_types(s1
->t
, s2
->t
))
3829 /* XXX: not complete */
3830 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3834 while (s1
!= NULL
) {
3837 if (!is_compatible_types(s1
->t
, s2
->t
))
3846 /* XXX: not complete */
3851 /* print a type. If 'varstr' is not NULL, then the variable is also
3852 printed in the type */
3854 /* XXX: add array and function pointers */
3855 void type_to_str(char *buf
, int buf_size
,
3856 int t
, const char *varstr
)
3866 if (t
& VT_UNSIGNED
)
3867 pstrcat(buf
, buf_size
, "unsigned ");
3897 tstr
= "long double";
3899 pstrcat(buf
, buf_size
, tstr
);
3903 if (bt
== VT_STRUCT
)
3907 pstrcat(buf
, buf_size
, tstr
);
3908 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3909 if (v
>= SYM_FIRST_ANOM
)
3910 pstrcat(buf
, buf_size
, "<anonymous>");
3912 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3915 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3916 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3917 pstrcat(buf
, buf_size
, "(");
3919 while (sa
!= NULL
) {
3920 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3921 pstrcat(buf
, buf_size
, buf1
);
3924 pstrcat(buf
, buf_size
, ", ");
3926 pstrcat(buf
, buf_size
, ")");
3929 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3930 pstrcpy(buf1
, sizeof(buf1
), "*");
3932 pstrcat(buf1
, sizeof(buf1
), varstr
);
3933 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3937 pstrcat(buf
, buf_size
, " ");
3938 pstrcat(buf
, buf_size
, varstr
);
3943 /* verify type compatibility to store vtop in 'dt' type, and generate
3945 void gen_assign_cast(int dt
)
3948 char buf1
[256], buf2
[256];
3950 st
= vtop
->t
; /* source type */
3951 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3952 /* special cases for pointers */
3953 /* a function is implicitely a function pointer */
3954 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3955 if (!is_compatible_types(pointed_type(dt
), st
))
3960 /* '0' can also be a pointer */
3961 if ((st
& VT_BTYPE
) == VT_INT
&&
3962 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3966 if (!is_compatible_types(dt
, st
)) {
3968 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3969 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3970 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3976 /* store vtop in lvalue pushed on stack */
3979 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3983 sbt
= vtop
->t
& VT_BTYPE
;
3984 dbt
= ft
& VT_BTYPE
;
3985 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3986 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3987 /* optimize char/short casts */
3988 delayed_cast
= VT_MUSTCAST
;
3989 vtop
->t
= ft
& VT_TYPE
;
3992 gen_assign_cast(ft
& VT_TYPE
);
3995 if (sbt
== VT_STRUCT
) {
3996 /* if structure, only generate pointer */
3997 /* structure assignment : generate memcpy */
3998 /* XXX: optimize if small size */
4000 gfunc_start(&gf
, FUNC_CDECL
);
4002 size
= type_size(vtop
->t
, &align
);
4016 vpushi((int)&memcpy
);
4018 /* leave source on stack */
4019 } else if (ft
& VT_BITFIELD
) {
4020 /* bitfield store handling */
4021 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4022 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4023 /* remove bit field info to avoid loops */
4024 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4026 /* duplicate destination */
4028 vtop
[-1] = vtop
[-2];
4030 /* mask and shift source */
4031 vpushi((1 << bit_size
) - 1);
4035 /* load destination, mask and or with source */
4037 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4043 #ifdef CONFIG_TCC_BCHECK
4044 /* bound check case */
4045 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4054 r
= gv(rc
); /* generate value */
4055 /* if lvalue was saved on stack, must read it */
4056 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4058 t
= get_reg(RC_INT
);
4060 sv
.r
= VT_LOCAL
| VT_LVAL
;
4061 sv
.c
.ul
= vtop
[-1].c
.ul
;
4063 vtop
[-1].r
= t
| VT_LVAL
;
4066 /* two word case handling : store second register at word + 4 */
4067 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4069 /* convert to int to increment easily */
4076 /* XXX: it works because r2 is spilled last ! */
4077 store(vtop
->r2
, vtop
- 1);
4080 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4081 vtop
->r
|= delayed_cast
;
4085 /* post defines POST/PRE add. c is the token ++ or -- */
4086 void inc(int post
, int c
)
4089 vdup(); /* save lvalue */
4091 gv_dup(); /* duplicate value */
4096 vpushi(c
- TOK_MID
);
4098 vstore(); /* store value */
4100 vpop(); /* if post op, return saved value */
4103 /* Parse GNUC __attribute__ extension. Currently, the following
4104 extensions are recognized:
4105 - aligned(n) : set data/function alignment.
4106 - section(x) : generate data/code in this section.
4107 - unused : currently ignored, but may be used someday.
4109 void parse_attribute(AttributeDef
*ad
)
4116 while (tok
!= ')') {
4117 if (tok
< TOK_IDENT
)
4118 expect("attribute name");
4123 case TOK___SECTION__
:
4126 expect("section name");
4127 ad
->section
= find_section(tokc
.ts
->str
);
4132 case TOK___ALIGNED__
:
4135 if (n
<= 0 || (n
& (n
- 1)) != 0)
4136 error("alignment must be a positive power of two");
4141 case TOK___UNUSED__
:
4142 /* currently, no need to handle it because tcc does not
4143 track unused objects */
4146 case TOK___NORETURN__
:
4147 /* currently, no need to handle it because tcc does not
4148 track unused objects */
4153 ad
->func_call
= FUNC_CDECL
;
4157 case TOK___STDCALL__
:
4158 ad
->func_call
= FUNC_STDCALL
;
4161 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4162 /* skip parameters */
4163 /* XXX: skip parenthesis too */
4166 while (tok
!= ')' && tok
!= -1)
4180 /* enum/struct/union declaration */
4181 int struct_decl(int u
)
4183 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4184 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4188 a
= tok
; /* save decl type */
4193 /* struct already defined ? return it */
4194 /* XXX: check consistency */
4195 s
= sym_find(v
| SYM_STRUCT
);
4198 error("invalid type");
4204 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4205 /* put struct/union/enum name in type */
4207 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4212 error("struct/union/enum already defined");
4213 /* cannot be empty */
4220 if (a
== TOK_ENUM
) {
4227 /* enum symbols have static storage */
4228 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4233 parse_btype(&b
, &ad
);
4238 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4239 if ((t
& VT_BTYPE
) == VT_FUNC
||
4240 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4241 error("invalid type for '%s'",
4242 get_tok_str(v
, NULL
));
4248 bit_size
= expr_const();
4249 /* XXX: handle v = 0 case for messages */
4251 error("negative width in bit-field '%s'",
4252 get_tok_str(v
, NULL
));
4253 if (v
&& bit_size
== 0)
4254 error("zero width for bit-field '%s'",
4255 get_tok_str(v
, NULL
));
4257 size
= type_size(t
, &align
);
4259 if (bit_size
>= 0) {
4264 error("bitfields must have scalar type");
4266 if (bit_size
> bsize
) {
4267 error("width of '%s' exceeds its type",
4268 get_tok_str(v
, NULL
));
4269 } else if (bit_size
== bsize
) {
4270 /* no need for bit fields */
4272 } else if (bit_size
== 0) {
4273 /* XXX: what to do if only padding in a
4275 /* zero size: means to pad */
4279 /* we do not have enough room ? */
4280 if ((bit_pos
+ bit_size
) > bsize
)
4283 /* XXX: handle LSB first */
4285 (bit_pos
<< VT_STRUCT_SHIFT
) |
4286 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4287 bit_pos
+= bit_size
;
4293 /* add new memory data only if starting
4295 if (lbit_pos
== 0) {
4296 if (a
== TOK_STRUCT
) {
4297 c
= (c
+ align
- 1) & -align
;
4305 if (align
> maxalign
)
4309 printf("add field %s offset=%d",
4310 get_tok_str(v
, NULL
), offset
);
4311 if (t
& VT_BITFIELD
) {
4312 printf(" pos=%d size=%d",
4313 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4314 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4318 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4322 if (tok
== ';' || tok
== -1)
4332 /* size for struct/union, dummy for enum */
4333 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4338 /* return 0 if no type declaration. otherwise, return the basic type
4341 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4343 int t
, u
, type_found
;
4346 memset(ad
, 0, sizeof(AttributeDef
));
4357 if ((t
& VT_BTYPE
) != 0)
4358 error("too many basic types");
4372 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4373 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4374 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4375 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4389 if ((t
& VT_BTYPE
) == VT_LONG
) {
4390 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4397 u
= struct_decl(VT_ENUM
);
4401 u
= struct_decl(VT_STRUCT
);
4404 /* type modifiers */
4409 case TOK___SIGNED__
:
4412 case TOK___INLINE__
:
4434 /* GNUC attribute */
4435 case TOK___ATTRIBUTE__
:
4436 parse_attribute(ad
);
4440 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4442 t
|= (s
->t
& ~VT_TYPEDEF
);
4449 /* long is never used as type */
4450 if ((t
& VT_BTYPE
) == VT_LONG
)
4451 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4456 int post_type(int t
, AttributeDef
*ad
)
4458 int p
, n
, pt
, l
, t1
;
4459 Sym
**plast
, *s
, *first
;
4463 /* function declaration */
4468 while (tok
!= ')') {
4469 /* read param name and compute offset */
4470 if (l
!= FUNC_OLD
) {
4471 if (!parse_btype(&pt
, &ad1
)) {
4473 error("invalid type");
4480 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4482 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4483 if ((pt
& VT_BTYPE
) == VT_VOID
)
4484 error("parameter declared as void");
4491 /* array must be transformed to pointer according to ANSI C */
4493 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4498 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4505 /* if no parameters, then old type prototype */
4509 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4510 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4511 /* we push a anonymous symbol which will contain the function prototype */
4513 s
= sym_push(p
, t
, ad
->func_call
, l
);
4515 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4516 } else if (tok
== '[') {
4517 /* array definition */
4523 error("invalid array size");
4526 /* parse next post type */
4527 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4528 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4530 /* we push a anonymous symbol which will contain the array
4533 sym_push(p
, t
, 0, n
);
4534 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4539 /* Read a type declaration (except basic type), and return the
4540 type. 'td' is a bitmask indicating which kind of type decl is
4541 expected. 't' should contain the basic type. 'ad' is the attribute
4542 definition of the basic type. It can be modified by type_decl(). */
4543 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4548 while (tok
== '*') {
4550 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4555 /* recursive type */
4556 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4559 /* XXX: this is not correct to modify 'ad' at this point, but
4560 the syntax is not clear */
4561 if (tok
== TOK___ATTRIBUTE__
)
4562 parse_attribute(ad
);
4563 u
= type_decl(ad
, v
, 0, td
);
4567 /* type identifier */
4568 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4572 if (!(td
& TYPE_ABSTRACT
))
4573 expect("identifier");
4577 /* append t at the end of u */
4578 t
= post_type(t
, ad
);
4579 if (tok
== TOK___ATTRIBUTE__
)
4580 parse_attribute(ad
);
4585 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4595 /* define a new external reference to a symbol 'v' of type 'u' */
4596 Sym
*external_sym(int v
, int u
, int r
)
4602 /* push forward reference */
4603 s
= sym_push1(&global_stack
,
4604 v
, u
| VT_EXTERN
, 0);
4605 s
->r
= r
| VT_CONST
| VT_SYM
;
4610 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4611 static int lvalue_type(int t
)
4618 else if (bt
== VT_SHORT
)
4622 if (t
& VT_UNSIGNED
)
4623 r
|= VT_LVAL_UNSIGNED
;
4627 /* indirection with full error checking and bound check */
4628 static void indir(void)
4630 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4632 if (vtop
->r
& VT_LVAL
)
4634 vtop
->t
= pointed_type(vtop
->t
);
4635 /* an array is never an lvalue */
4636 if (!(vtop
->t
& VT_ARRAY
)) {
4637 vtop
->r
|= lvalue_type(vtop
->t
);
4638 /* if bound checking, the referenced pointer must be checked */
4639 if (do_bounds_check
)
4640 vtop
->r
|= VT_MUSTBOUND
;
4644 /* pass a parameter to a function and do type checking and casting */
4645 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4648 func_type
= func
->c
;
4649 if (func_type
== FUNC_OLD
||
4650 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4651 /* default casting : only need to convert float to double */
4652 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4653 gen_cast(VT_DOUBLE
);
4654 } else if (arg
== NULL
) {
4655 error("too many arguments to function");
4657 gen_assign_cast(arg
->t
);
4664 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
4669 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4672 } else if (tok
== TOK_CUINT
) {
4673 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4675 } else if (tok
== TOK_CLLONG
) {
4676 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4678 } else if (tok
== TOK_CULLONG
) {
4679 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4681 } else if (tok
== TOK_CFLOAT
) {
4682 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4684 } else if (tok
== TOK_CDOUBLE
) {
4685 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4687 } else if (tok
== TOK_CLDOUBLE
) {
4688 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4690 } else if (tok
== TOK___FUNC__
) {
4691 /* special function name identifier */
4692 /* generate (char *) type */
4693 data_offset
= data_section
->data_ptr
- data_section
->data
;
4694 vpush_ref(mk_pointer(VT_BYTE
), data_section
, data_offset
);
4695 strcpy(data_section
->data
+ data_offset
, funcname
);
4696 data_offset
+= strlen(funcname
) + 1;
4697 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4699 } else if (tok
== TOK_LSTR
) {
4702 } else if (tok
== TOK_STR
) {
4703 /* string parsing */
4706 type_size(t
, &align
);
4707 data_offset
= data_section
->data_ptr
- data_section
->data
;
4708 data_offset
= (data_offset
+ align
- 1) & -align
;
4710 /* we must declare it as an array first to use initializer parser */
4711 t
= VT_ARRAY
| mk_pointer(t
);
4712 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4713 data_offset
+= type_size(t
, &align
);
4714 /* put it as pointer */
4715 vpush_ref(t
& ~VT_ARRAY
, data_section
, fc
);
4716 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4722 if (parse_btype(&t
, &ad
)) {
4723 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4725 /* check ISOC99 compound literal */
4727 /* data is allocated locally by default */
4732 /* all except arrays are lvalues */
4733 if (!(ft
& VT_ARRAY
))
4734 r
|= lvalue_type(ft
);
4735 memset(&ad
, 0, sizeof(AttributeDef
));
4736 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4745 } else if (t
== '*') {
4748 } else if (t
== '&') {
4750 /* functions names must be treated as function pointers,
4751 except for unary '&' and sizeof. Since we consider that
4752 functions are not lvalues, we only have to handle it
4753 there and in function calls. */
4754 /* arrays can also be used although they are not lvalues */
4755 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4756 !(vtop
->t
& VT_ARRAY
))
4758 vtop
->t
= mk_pointer(vtop
->t
);
4763 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4764 vtop
->c
.i
= !vtop
->c
.i
;
4765 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4766 vtop
->c
.i
= vtop
->c
.i
^ 1;
4768 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4778 if (t
== TOK_SIZEOF
) {
4781 if (parse_btype(&t
, &ad
)) {
4782 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4784 /* XXX: some code could be generated: add eval
4796 vpushi(type_size(t
, &t
));
4798 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4801 } else if (t
== '-') {
4808 expect("identifier");
4812 error("'%s' undeclared", get_tok_str(t
, NULL
));
4813 /* for simple function calls, we tolerate undeclared
4814 external reference */
4816 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4817 /* int() function */
4818 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4820 vset(s
->t
, s
->r
, s
->c
);
4821 /* if forward reference, we must point to s */
4822 if (vtop
->r
& VT_SYM
)
4827 /* post operations */
4829 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4832 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4834 if (tok
== TOK_ARROW
)
4839 /* expect pointer on structure */
4840 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4841 expect("struct or union");
4842 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4845 while ((s
= s
->next
) != NULL
) {
4850 error("field not found");
4851 /* add field offset to pointer */
4852 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4855 /* change type to field type, and set to lvalue */
4857 /* an array is never an lvalue */
4858 if (!(vtop
->t
& VT_ARRAY
))
4859 vtop
->r
|= lvalue_type(vtop
->t
);
4861 } else if (tok
== '[') {
4867 } else if (tok
== '(') {
4872 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4873 /* pointer test (no array accepted) */
4874 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4875 vtop
->t
= pointed_type(vtop
->t
);
4876 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4880 expect("function pointer");
4883 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4885 /* get return type */
4886 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4887 save_regs(0); /* save used temporary registers */
4888 gfunc_start(&gf
, s
->r
);
4890 sa
= s
->next
; /* first parameter */
4891 #ifdef INVERT_FUNC_PARAMS
4895 ParseState saved_parse_state
;
4898 /* read each argument and store it on a stack */
4899 /* XXX: merge it with macro args ? */
4905 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4909 else if (tok
== ')')
4911 tok_str_add_tok(&str
);
4914 tok_str_add(&str
, -1); /* end of file added */
4915 tok_str_add(&str
, 0);
4916 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4917 s1
->next
= sa
; /* add reference to argument */
4926 /* now generate code in reverse order by reading the stack */
4927 save_parse_state(&saved_parse_state
);
4929 macro_ptr
= (int *)args
->c
;
4933 expect("',' or ')'");
4934 gfunc_param_typed(&gf
, s
, args
->next
);
4936 free((int *)args
->c
);
4940 restore_parse_state(&saved_parse_state
);
4943 /* compute first implicit argument if a structure is returned */
4944 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4945 /* get some space for the returned structure */
4946 size
= type_size(s
->t
, &align
);
4947 loc
= (loc
- size
) & -align
;
4949 ret
.r
= VT_LOCAL
| VT_LVAL
;
4950 /* pass it as 'int' to avoid structure arg passing
4952 vset(VT_INT
, VT_LOCAL
, loc
);
4958 /* return in register */
4959 if (is_float(ret
.t
)) {
4962 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4968 #ifndef INVERT_FUNC_PARAMS
4972 gfunc_param_typed(&gf
, s
, sa
);
4982 error("too few arguments to function");
4986 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5000 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5001 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5002 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5025 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5026 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5027 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5028 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5029 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5030 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5031 (l
== 5 && tok
== '&') ||
5032 (l
== 6 && tok
== '^') ||
5033 (l
== 7 && tok
== '|') ||
5034 (l
== 8 && tok
== TOK_LAND
) ||
5035 (l
== 9 && tok
== TOK_LOR
)) {
5044 /* only used if non constant */
5052 if (tok
!= TOK_LAND
) {
5055 vset(VT_INT
, VT_JMPI
, t
);
5072 if (tok
!= TOK_LOR
) {
5075 vset(VT_INT
, VT_JMP
, t
);
5085 /* XXX: better constant handling */
5088 int t
, u
, c
, r1
, r2
, rc
;
5108 save_regs(1); /* we need to save all registers here except
5109 at the top because it is a branch point */
5112 /* XXX: long long handling ? */
5114 if (is_float(vtop
->t
))
5117 vtop
--; /* no vpop so that FP stack is not flushed */
5142 /* parse a constant expression and return value in vtop */
5143 void expr_const1(void)
5149 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5154 /* parse an integer constant and return its value */
5155 int expr_const(void)
5164 /* return the label token if current token is a label, otherwise
5171 /* fast test first */
5172 if (tok
< TOK_UIDENT
)
5174 /* no need to save tokc since we expect an identifier */
5182 /* XXX: may not work in all cases (macros ?) */
5191 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5196 /* generate line number info */
5198 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5199 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5201 last_line_num
= file
->line_num
;
5204 if (tok
== TOK_IF
) {
5211 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5213 if (c
== TOK_ELSE
) {
5217 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5218 gsym(d
); /* patch else jmp */
5221 } else if (tok
== TOK_WHILE
) {
5229 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5233 } else if (tok
== '{') {
5236 s
= local_stack
.top
;
5237 while (tok
!= '}') {
5240 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5242 /* pop locally defined symbols */
5243 sym_pop(&local_stack
, s
);
5245 } else if (tok
== TOK_RETURN
) {
5249 gen_assign_cast(func_vt
);
5250 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5251 /* if returning structure, must copy it to implicit
5252 first pointer arg location */
5253 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5256 /* copy structure value to pointer */
5258 } else if (is_float(func_vt
)) {
5263 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5266 rsym
= gjmp(rsym
); /* jmp */
5267 } else if (tok
== TOK_BREAK
) {
5270 error("cannot break");
5271 *bsym
= gjmp(*bsym
);
5274 } else if (tok
== TOK_CONTINUE
) {
5277 error("cannot continue");
5278 *csym
= gjmp(*csym
);
5281 } else if (tok
== TOK_FOR
) {
5308 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5313 if (tok
== TOK_DO
) {
5318 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5329 if (tok
== TOK_SWITCH
) {
5333 /* XXX: other types than integer */
5334 case_reg
= gv(RC_INT
);
5338 b
= gjmp(0); /* jump to first case */
5340 block(&a
, csym
, &b
, &c
, case_reg
);
5341 /* if no default, jmp after switch */
5349 if (tok
== TOK_CASE
) {
5356 if (gnu_ext
&& tok
== TOK_DOTS
) {
5360 warning("empty case range");
5362 /* since a case is like a label, we must skip it with a jmp */
5365 vset(VT_INT
, case_reg
, 0);
5369 *case_sym
= gtst(1, 0);
5372 *case_sym
= gtst(1, 0);
5373 vset(VT_INT
, case_reg
, 0);
5376 *case_sym
= gtst(1, *case_sym
);
5380 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5382 if (tok
== TOK_DEFAULT
) {
5388 error("too many 'default'");
5390 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5392 if (tok
== TOK_GOTO
) {
5394 s
= sym_find1(&label_stack
, tok
);
5395 /* put forward definition if needed */
5397 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5398 /* label already defined */
5399 if (s
->t
& LABEL_FORWARD
)
5409 s
= sym_find1(&label_stack
, b
);
5411 if (!(s
->t
& LABEL_FORWARD
))
5412 error("multiple defined label");
5417 sym_push1(&label_stack
, b
, 0, ind
);
5419 /* we accept this, but it is a mistake */
5421 warning("deprecated use of label at end of compound statement");
5423 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5425 /* expression case */
5435 /* t is the array or struct type. c is the array or struct
5436 address. cur_index/cur_field is the pointer to the current
5437 value. 'size_only' is true if only size info is needed (only used
5439 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5440 int *cur_index
, Sym
**cur_field
,
5444 int notfirst
, index
, align
, l
;
5447 if (gnu_ext
&& (l
= is_label()) != 0)
5450 while (tok
== '[' || tok
== '.') {
5452 if (!(t
& VT_ARRAY
))
5453 expect("array type");
5454 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5456 index
= expr_const();
5457 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5458 expect("invalid index");
5462 t
= pointed_type(t
);
5463 c
+= index
* type_size(t
, &align
);
5469 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5470 expect("struct/union type");
5471 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5483 t
= f
->t
| (t
& ~VT_TYPE
);
5498 t
= pointed_type(t
);
5499 c
+= index
* type_size(t
, &align
);
5503 error("too many field init");
5504 t
= f
->t
| (t
& ~VT_TYPE
);
5508 decl_initializer(t
, sec
, c
, 0, size_only
);
5512 #define EXPR_CONST 1
5515 /* store a value or an expression directly in global data or in local array */
5516 void init_putv(int t
, Section
*sec
, unsigned long c
,
5517 int v
, int expr_type
)
5519 int saved_global_expr
, bt
;
5527 /* compound literals must be allocated globally in this case */
5528 saved_global_expr
= global_expr
;
5531 global_expr
= saved_global_expr
;
5539 /* XXX: not portable */
5540 /* XXX: generate error if incorrect relocation */
5543 ptr
= sec
->data
+ c
;
5544 if ((vtop
->r
& VT_SYM
) &&
5550 error("initializer element is not computable at load time");
5553 *(char *)ptr
= vtop
->c
.i
;
5556 *(short *)ptr
= vtop
->c
.i
;
5559 *(double *)ptr
= vtop
->c
.d
;
5562 *(long double *)ptr
= vtop
->c
.ld
;
5565 *(long long *)ptr
= vtop
->c
.ll
;
5568 if (vtop
->r
& VT_SYM
) {
5569 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5572 *(int *)ptr
= vtop
->c
.i
;
5578 vset(t
, VT_LOCAL
, c
);
5585 /* put zeros for variable based init */
5586 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5591 /* nothing to do because globals are already set to zero */
5593 gfunc_start(&gf
, FUNC_CDECL
);
5598 vset(VT_INT
, VT_LOCAL
, c
);
5600 vpushi((int)&memset
);
5605 /* 't' contains the type and storage info. 'c' is the offset of the
5606 object in section 'sec'. If 'sec' is NULL, it means stack based
5607 allocation. 'first' is true if array '{' must be read (multi
5608 dimension implicit array init handling). 'size_only' is true if
5609 size only evaluation is wanted (only for arrays). */
5610 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5612 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5613 int t1
, size1
, align1
, expr_type
;
5618 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5621 t1
= pointed_type(t
);
5622 size1
= type_size(t1
, &align1
);
5625 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5631 /* only parse strings here if correct type (otherwise: handle
5632 them as ((w)char *) expressions */
5633 if ((tok
== TOK_LSTR
&&
5634 (t1
& VT_BTYPE
) == VT_INT
) ||
5636 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5637 /* XXX: move multiple string parsing in parser ? */
5638 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5640 /* compute maximum number of chars wanted */
5642 if (n
>= 0 && nb
> (n
- array_length
))
5643 nb
= n
- array_length
;
5646 warning("initializer-string for array is too long");
5648 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5649 ts
->str
[i
], EXPR_VAL
);
5655 /* only add trailing zero if enough storage (no
5656 warning in this case since it is standard) */
5657 if (n
< 0 || array_length
< n
) {
5659 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5665 while (tok
!= '}') {
5666 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5667 if (n
>= 0 && index
>= n
)
5668 error("index too large");
5669 /* must put zero in holes (note that doing it that way
5670 ensures that it even works with designators) */
5671 if (!size_only
&& array_length
< index
) {
5672 init_putz(t1
, sec
, c
+ array_length
* size1
,
5673 (index
- array_length
) * size1
);
5676 if (index
> array_length
)
5677 array_length
= index
;
5678 /* special test for multi dimensional arrays (may not
5679 be strictly correct if designators are used at the
5681 if (index
>= n
&& no_oblock
)
5690 /* put zeros at the end */
5691 if (!size_only
&& n
>= 0 && array_length
< n
) {
5692 init_putz(t1
, sec
, c
+ array_length
* size1
,
5693 (n
- array_length
) * size1
);
5695 /* patch type size if needed */
5697 s
->c
= array_length
;
5698 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5699 /* XXX: union needs only one init */
5701 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5706 while (tok
!= '}') {
5707 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5708 /* fill with zero between fields */
5710 if (!size_only
&& array_length
< index
) {
5711 init_putz(t
, sec
, c
+ array_length
,
5712 index
- array_length
);
5714 index
= index
+ type_size(f
->t
, &align1
);
5715 if (index
> array_length
)
5716 array_length
= index
;
5722 /* put zeros at the end */
5723 if (!size_only
&& array_length
< n
) {
5724 init_putz(t
, sec
, c
+ array_length
,
5728 } else if (tok
== '{') {
5730 decl_initializer(t
, sec
, c
, first
, size_only
);
5732 } else if (size_only
) {
5733 /* just skip expression */
5735 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5739 else if (tok
== ')')
5744 /* currently, we always use constant expression for globals
5745 (may change for scripting case) */
5746 expr_type
= EXPR_CONST
;
5748 expr_type
= EXPR_ANY
;
5749 init_putv(t
, sec
, c
, 0, expr_type
);
5753 /* parse an initializer for type 't' if 'has_init' is true, and
5754 allocate space in local or global data space ('r' is either
5755 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5756 variable 'v' of scope 'scope' is declared before initializers are
5757 parsed. If 'v' is zero, then a reference to the new object is put
5758 in the value stack. */
5759 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5762 int size
, align
, addr
, data_offset
;
5764 ParseState saved_parse_state
;
5765 TokenString init_str
;
5768 size
= type_size(t
, &align
);
5769 /* If unknown size, we must evaluate it before
5770 evaluating initializers because
5771 initializers can generate global data too
5772 (e.g. string pointers or ISOC99 compound
5773 literals). It also simplifies local
5774 initializers handling */
5775 tok_str_new(&init_str
);
5778 error("unknown type size");
5779 /* get all init string */
5781 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5783 error("unexpected end of file in initializer");
5784 tok_str_add_tok(&init_str
);
5787 else if (tok
== '}') {
5794 tok_str_add(&init_str
, -1);
5795 tok_str_add(&init_str
, 0);
5798 save_parse_state(&saved_parse_state
);
5800 macro_ptr
= init_str
.str
;
5802 decl_initializer(t
, NULL
, 0, 1, 1);
5803 /* prepare second initializer parsing */
5804 macro_ptr
= init_str
.str
;
5807 /* if still unknown size, error */
5808 size
= type_size(t
, &align
);
5810 error("unknown type size");
5812 /* take into account specified alignment if bigger */
5813 if (ad
->aligned
> align
)
5814 align
= ad
->aligned
;
5815 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5817 if (do_bounds_check
&& (t
& VT_ARRAY
))
5819 #ifdef TCC_TARGET_IL
5820 /* XXX: ugly patch to allocate local variables for IL, just
5825 loc
= (loc
- size
) & -align
;
5828 /* handles bounds */
5829 /* XXX: currently, since we do only one pass, we cannot track
5830 '&' operators, so we add only arrays */
5831 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5833 /* add padding between regions */
5835 /* then add local bound info */
5836 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5837 *bounds_ptr
++ = addr
;
5838 *bounds_ptr
++ = size
;
5839 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5842 /* compute section */
5850 data_offset
= sec
->data_ptr
- sec
->data
;
5851 data_offset
= (data_offset
+ align
- 1) & -align
;
5853 /* very important to increment global pointer at this time
5854 because initializers themselves can create new initializers */
5855 data_offset
+= size
;
5856 /* handles bounds */
5857 if (do_bounds_check
) {
5859 /* first, we need to add at least one byte between each region */
5861 /* then add global bound info */
5862 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5863 /* XXX: add relocation */
5864 *bounds_ptr
++ = addr
+ (unsigned long)sec
->data
;
5865 *bounds_ptr
++ = size
;
5866 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5868 sec
->data_ptr
= sec
->data
+ data_offset
;
5874 /* local variable */
5875 sym_push(v
, t
, r
, addr
);
5877 if (scope
== VT_CONST
) {
5878 /* global scope: see if already defined */
5882 if (!is_compatible_types(sym
->t
, t
))
5883 error("incompatible types for redefinition of '%s'",
5884 get_tok_str(v
, NULL
));
5885 if (!(sym
->t
& VT_EXTERN
))
5886 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5887 sym
->t
&= ~VT_EXTERN
;
5890 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5892 put_extern_sym(sym
, sec
, addr
);
5896 /* push local reference */
5899 /* push global reference */
5900 vpush_ref(t
, sec
, addr
);
5904 decl_initializer(t
, sec
, addr
, 1, 0);
5905 /* restore parse state if needed */
5908 restore_parse_state(&saved_parse_state
);
5913 void put_func_debug(int t
)
5918 /* XXX: we put here a dummy type */
5919 snprintf(buf
, sizeof(buf
), "%s:%c1",
5920 funcname
, t
& VT_STATIC
? 'f' : 'F');
5921 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5927 /* not finished : try to put some local vars in registers */
5928 //#define CONFIG_REG_VARS
5930 #ifdef CONFIG_REG_VARS
5931 void add_var_ref(int t
)
5933 printf("%s:%d: &%s\n",
5934 file
->filename
, file
->line_num
,
5935 get_tok_str(t
, NULL
));
5938 /* first pass on a function with heuristic to extract variable usage
5939 and pointer references to local variables for register allocation */
5940 void analyse_function(void)
5947 /* any symbol coming after '&' is considered as being a
5948 variable whose reference is taken. It is highly unaccurate
5949 but it is difficult to do better without a complete parse */
5952 /* if '& number', then no need to examine next tokens */
5953 if (tok
== TOK_CINT
||
5955 tok
== TOK_CLLONG
||
5956 tok
== TOK_CULLONG
) {
5958 } else if (tok
>= TOK_UIDENT
) {
5959 /* if '& ident [' or '& ident ->', then ident address
5963 if (tok
!= '[' && tok
!= TOK_ARROW
)
5967 while (tok
!= '}' && tok
!= ';' &&
5968 !((tok
== ',' || tok
== ')') && level
== 0)) {
5969 if (tok
>= TOK_UIDENT
) {
5971 } else if (tok
== '(') {
5973 } else if (tok
== ')') {
5986 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5989 int t
, b
, v
, has_init
, r
;
5994 if (!parse_btype(&b
, &ad
)) {
5995 /* skip redundant ';' */
5996 /* XXX: find more elegant solution */
6001 /* special test for old K&R protos without explicit int
6002 type. Only accepted when defining global data */
6003 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6007 if (((b
& VT_BTYPE
) == VT_ENUM
||
6008 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6010 /* we accept no variable after */
6014 while (1) { /* iterate thru each declaration */
6015 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6019 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6020 printf("type = '%s'\n", buf
);
6024 #ifdef CONFIG_REG_VARS
6025 TokenString func_str
;
6026 ParseState saved_parse_state
;
6031 error("cannot use local functions");
6033 expect("function definition");
6035 #ifdef CONFIG_REG_VARS
6036 /* parse all function code and record it */
6038 tok_str_new(&func_str
);
6044 error("unexpected end of file");
6045 tok_str_add_tok(&func_str
);
6050 } else if (t
== '}') {
6052 if (block_level
== 0)
6056 tok_str_add(&func_str
, -1);
6057 tok_str_add(&func_str
, 0);
6059 save_parse_state(&saved_parse_state
);
6061 macro_ptr
= func_str
.str
;
6066 /* compute text section */
6067 cur_text_section
= ad
.section
;
6068 if (!cur_text_section
)
6069 cur_text_section
= text_section
;
6070 ind
= (int)cur_text_section
->data_ptr
;
6071 funcname
= get_tok_str(v
, NULL
);
6074 /* if symbol is already defined, then put complete type */
6077 /* put function symbol */
6078 sym
= sym_push1(&global_stack
, v
, t
, 0);
6080 put_extern_sym(sym
, cur_text_section
,
6081 ind
- (int)cur_text_section
->data
);
6082 sym
->r
= VT_SYM
| VT_CONST
;
6083 /* put debug symbol */
6086 /* push a dummy symbol to enable local sym storage */
6087 sym_push1(&local_stack
, 0, 0, 0);
6091 #ifdef CONFIG_REG_VARS
6092 macro_ptr
= func_str
.str
;
6095 block(NULL
, NULL
, NULL
, NULL
, 0);
6098 cur_text_section
->data_ptr
= (unsigned char *)ind
;
6099 sym_pop(&label_stack
, NULL
); /* reset label stack */
6100 sym_pop(&local_stack
, NULL
); /* reset local stack */
6101 /* end of function */
6103 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6105 funcname
= ""; /* for safety */
6106 func_vt
= VT_VOID
; /* for safety */
6107 ind
= 0; /* for safety */
6109 #ifdef CONFIG_REG_VARS
6111 restore_parse_state(&saved_parse_state
);
6115 if (b
& VT_TYPEDEF
) {
6116 /* save typedefed type */
6117 /* XXX: test storage specifiers ? */
6118 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6119 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6120 /* external function definition */
6121 external_sym(v
, t
, 0);
6123 /* not lvalue if array */
6125 if (!(t
& VT_ARRAY
))
6126 r
|= lvalue_type(t
);
6127 if (b
& VT_EXTERN
) {
6128 /* external variable */
6129 external_sym(v
, t
, r
);
6135 has_init
= (tok
== '=');
6138 decl_initializer_alloc(t
, &ad
, r
,
6152 /* compile the C file opened in 'file'. Return non zero if errors. */
6153 int tcc_compile(TCCState
*s
)
6159 include_stack_ptr
= include_stack
;
6160 ifdef_stack_ptr
= ifdef_stack
;
6163 anon_sym
= SYM_FIRST_ANOM
;
6165 /* file info: full path + filename */
6167 getcwd(buf
, sizeof(buf
));
6168 pstrcat(buf
, sizeof(buf
), "/");
6169 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6170 put_stabs(file
->filename
, N_SO
, 0, 0,
6171 (unsigned long)text_section
->data_ptr
);
6173 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6174 symbols can be safely used */
6175 put_elf_sym(symtab_section
, 0, 0,
6176 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6177 SHN_ABS
, file
->filename
);
6179 /* define common 'char *' type because it is often used internally
6180 for arrays and struct dereference */
6181 char_pointer_type
= mk_pointer(VT_BYTE
);
6183 define_start
= define_stack
.top
;
6185 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6189 expect("declaration");
6191 /* end of translation unit info */
6193 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6196 /* reset define stack, but leave -Dsymbols (may be incorrect if
6197 they are undefined) */
6198 sym_pop(&define_stack
, define_start
);
6200 sym_pop(&global_stack
, NULL
);
6205 int tcc_compile_file(TCCState
*s
, const char *filename1
)
6208 file
= tcc_open(filename1
);
6210 error("file '%s' not found", filename1
);
6211 ret
= tcc_compile(s
);
6216 int tcc_compile_string(TCCState
*s
, const char *str
)
6218 BufferedFile bf1
, *bf
= &bf1
;
6221 /* init file structure */
6223 bf
->buf_ptr
= (char *)str
;
6224 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6225 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6229 ret
= tcc_compile(s
);
6231 /* currently, no need to close */
6235 /* define a symbol. A value can also be provided with the '=' operator */
6236 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6238 BufferedFile bf1
, *bf
= &bf1
;
6240 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6241 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6245 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6247 /* init file structure */
6249 bf
->buf_ptr
= bf
->buffer
;
6250 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6251 bf
->filename
[0] = '\0';
6255 include_stack_ptr
= include_stack
;
6257 /* parse with define parser */
6259 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6265 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6269 ts
= tok_alloc(sym
, 0);
6270 s
= sym_find1(&define_stack
, tok
);
6271 /* undefine symbol by putting an invalid name */
6273 sym_undef(&define_stack
, s
);
6276 /* open a dynamic library so that its symbol are available for
6277 compiled programs */
6278 /* XXX: open the lib only to actually run the program */
6279 int tcc_add_dll(TCCState
*s
, const char *library_name
)
6283 h
= dlopen(library_name
, RTLD_GLOBAL
| RTLD_LAZY
);
6285 error((char *)dlerror());
6289 static int put_elf_str(Section
*s
, const char *sym
)
6292 offset
= s
->data_ptr
- s
->data
;
6302 /* elf symbol hashing function */
6303 static unsigned long elf_hash(const unsigned char *name
)
6305 unsigned long h
= 0, g
;
6308 h
= (h
<< 4) + *name
++;
6317 /* add one symbol in hash table if it is global */
6318 /* WARNING: must be called each time a symbol is added otherwise the
6319 hash table is not synchronized with the symbol table */
6320 static void update_hash_elf_sym(Section
*hs
,
6321 int sym_index
, int info
, const char *name
)
6325 /* only add global symbols */
6326 if (ELF32_ST_BIND(info
) == STB_GLOBAL
) {
6327 /* add another hashing entry */
6328 nbuckets
= ((int *)hs
->data
)[0];
6329 h
= elf_hash(name
) % nbuckets
;
6330 ((int *)hs
->data
)[2 + nbuckets
+ sym_index
] = ((int *)hs
->data
)[2 + h
];
6331 ((int *)hs
->data
)[2 + h
] = sym_index
;
6333 /* but still add room for all symbols */
6334 ((int *)hs
->data
)[1]++;
6335 hs
->data_ptr
+= sizeof(int);
6338 /* return the symbol number */
6339 static int put_elf_sym(Section
*s
,
6340 unsigned long value
, unsigned long size
,
6341 int info
, int other
, int shndx
, const char *name
)
6343 int name_offset
, sym_index
;
6347 sym
= (Elf32_Sym
*)s
->data_ptr
;
6349 name_offset
= put_elf_str(s
->link
, name
);
6352 /* XXX: endianness */
6353 sym
->st_name
= name_offset
;
6354 sym
->st_value
= value
;
6355 sym
->st_size
= size
;
6356 sym
->st_info
= info
;
6357 sym
->st_other
= other
;
6358 sym
->st_shndx
= shndx
;
6359 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6362 update_hash_elf_sym(hs
, sym_index
, info
, name
);
6364 s
->data_ptr
+= sizeof(Elf32_Sym
);
6368 /* find global ELF symbol 'name' and return its index. Return 0 if not
6370 static int find_elf_sym(Section
*s
, const char *name
)
6374 int nbuckets
, sym_index
, h
;
6380 nbuckets
= ((int *)hs
->data
)[0];
6381 h
= elf_hash(name
) % nbuckets
;
6382 sym_index
= ((int *)hs
->data
)[2 + h
];
6383 while (sym_index
!= 0) {
6384 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6385 name1
= s
->link
->data
+ sym
->st_name
;
6386 if (!strcmp(name
, name1
))
6388 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6393 /* update sym->c so that it points to an external symbol in section
6394 'section' with value 'value' */
6395 /* XXX: get rid of put_elf_sym */
6396 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
)
6398 int sym_type
, sym_bind
, sh_num
;
6403 sh_num
= section
->sh_num
;
6407 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6408 sym_type
= STT_FUNC
;
6410 sym_type
= STT_OBJECT
;
6411 if (sym
->t
& VT_STATIC
)
6412 sym_bind
= STB_LOCAL
;
6414 sym_bind
= STB_GLOBAL
;
6415 /* if the symbol is global, then we look if it is already
6417 name
= get_tok_str(sym
->v
, NULL
);
6418 if (sym_bind
== STB_GLOBAL
) {
6419 sym
->c
= find_elf_sym(symtab_section
, name
);
6422 /* check if not defined */
6424 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6425 if (esym
->st_shndx
!= SHN_UNDEF
)
6426 error("'%s' defined twice", name
);
6427 esym
->st_shndx
= sh_num
;
6428 esym
->st_value
= value
;
6432 sym
->c
= put_elf_sym(symtab_section
, value
, 0,
6433 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6437 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6438 esym
->st_value
= value
;
6439 esym
->st_shndx
= sh_num
;
6443 /* put relocation */
6444 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
6445 int type
, int symbol
)
6453 /* if no relocation section, create it */
6454 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6455 /* if the symtab is allocated, then we consider the relocation
6457 sr
= new_section(buf
, SHT_REL
, symtab
->sh_flags
);
6458 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6460 sr
->sh_info
= s
->sh_num
;
6463 rel
= (Elf32_Rel
*)sr
->data_ptr
;
6464 /* XXX: endianness */
6465 rel
->r_offset
= offset
;
6466 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6467 sr
->data_ptr
+= sizeof(Elf32_Rel
);
6470 /* put stab debug information */
6473 unsigned long n_strx
; /* index into string table of name */
6474 unsigned char n_type
; /* type of symbol */
6475 unsigned char n_other
; /* misc info (usually empty) */
6476 unsigned short n_desc
; /* description field */
6477 unsigned long n_value
; /* value of symbol */
6480 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
6484 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
6486 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6491 sym
->n_other
= other
;
6493 sym
->n_value
= value
;
6495 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
6498 static void put_stabn(int type
, int other
, int desc
, int value
)
6500 put_stabs(NULL
, type
, other
, desc
, value
);
6503 static void put_stabd(int type
, int other
, int desc
)
6505 put_stabs(NULL
, type
, other
, desc
, 0);
6508 /* In an ELF file symbol table, the local symbols must appear below
6509 the global and weak ones. Since TCC cannot sort it while generating
6510 the code, we must do it after. All the relocation tables are also
6511 modified to take into account the symbol table sorting */
6512 static void sort_symbols(Section
*s
)
6514 int *old_to_new_syms
;
6515 Elf32_Sym
*new_syms
;
6520 int type
, sym_index
;
6522 nb_syms
= (s
->data_ptr
- s
->data
) / sizeof(Elf32_Sym
);
6523 new_syms
= malloc(nb_syms
* sizeof(Elf32_Sym
));
6525 error("memory full");
6526 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
6527 if (!old_to_new_syms
)
6528 error("memory full");
6529 /* first pass for local symbols */
6530 p
= (Elf32_Sym
*)s
->data
;
6532 for(i
= 0; i
< nb_syms
; i
++) {
6533 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
6534 old_to_new_syms
[i
] = q
- new_syms
;
6539 /* save the number of local symbols in section header */
6540 s
->sh_info
= q
- new_syms
;
6542 /* then second pass for non local symbols */
6543 p
= (Elf32_Sym
*)s
->data
;
6544 for(i
= 0; i
< nb_syms
; i
++) {
6545 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
6546 old_to_new_syms
[i
] = q
- new_syms
;
6552 /* we copy the new symbols to the old */
6553 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
6556 /* now we modify all the relocations */
6557 for(sr
= first_section
; sr
!= NULL
; sr
= sr
->next
) {
6558 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
6559 for(rel
= (Elf32_Rel
*)sr
->data
;
6560 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6562 sym_index
= ELF32_R_SYM(rel
->r_info
);
6563 type
= ELF32_R_TYPE(rel
->r_info
);
6564 sym_index
= old_to_new_syms
[sym_index
];
6565 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
6570 free(old_to_new_syms
);
6573 static unsigned long get_sym_val(int sym_index
)
6578 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6579 val
= sym
->st_value
;
6580 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
6581 val
+= sections
[sym
->st_shndx
]->sh_addr
;
6585 /* relocate a given section */
6586 static void relocate_section(Section
*s
)
6595 for(rel
= (Elf32_Rel
*)sr
->data
;
6596 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6598 ptr
= s
->data
+ rel
->r_offset
;
6599 val
= get_sym_val(ELF32_R_SYM(rel
->r_info
));
6600 type
= ELF32_R_TYPE(rel
->r_info
);
6601 greloc_patch(ptr
, s
->sh_addr
+ rel
->r_offset
, val
, type
);
6605 static Section
*new_section_hash(const char *name
, int sh_flags
,
6606 int nb_buckets
, Section
*symtab
)
6609 hash
= new_section(name
, SHT_HASH
, sh_flags
);
6610 ((int *)hash
->data
)[0] = nb_buckets
;
6611 ((int *)hash
->data
)[1] = 1;
6612 hash
->sh_entsize
= sizeof(int);
6613 hash
->data_ptr
+= (2 + nb_buckets
+ 1) * sizeof(int);
6614 symtab
->hash
= hash
;
6615 hash
->link
= symtab
;
6619 /* put dynamic tag */
6620 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
6623 dyn
= (Elf32_Dyn
*)dynamic
->data_ptr
;
6625 dyn
->d_un
.d_val
= val
;
6626 dynamic
->data_ptr
+= sizeof(Elf32_Dyn
);
6629 /* add dynamic sections so that the executable is dynamically linked */
6630 static char elf_interp
[] = "/lib/ld-linux.so.2";
6632 #define ELF_START_ADDR 0x08048000
6633 #define ELF_PAGE_SIZE 0x1000
6635 /* XXX: suppress that */
6636 static void put32(unsigned char *p
, unsigned int val
)
6644 /* output an ELF file (currently, only for testing) */
6645 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6646 /* XXX: suppress unneeded sections */
6647 int tcc_output_file(TCCState
*s1
, const char *filename
, int file_type
)
6653 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
;
6655 Section
*strsec
, *s
;
6656 Elf32_Shdr shdr
, *sh
;
6657 Elf32_Phdr
*phdr
, *ph
;
6658 Section
*interp
, *plt
, *got
, *dynamic
, *dynsym
, *dynstr
, *hash
;
6659 unsigned char *saved_dynamic_data_ptr
;
6665 plt
= NULL
; /* avoid warning */
6666 got
= NULL
; /* avoid warning */
6667 dynsym
= NULL
; /* avoid warning */
6668 hash
= NULL
; /* avoid warning */
6669 dynstr
= NULL
; /* avoid warning */
6670 saved_dynamic_data_ptr
= NULL
; /* avoid warning */
6672 if (file_type
!= TCC_FILE_OBJ
&& !static_link
) {
6676 if (file_type
== TCC_FILE_EXE
) {
6677 /* add interpreter section only if executable */
6678 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
6679 interp
->sh_addralign
= 1;
6680 strcpy(interp
->data_ptr
, elf_interp
);
6681 interp
->data_ptr
+= sizeof(elf_interp
);
6684 /* add dynamic symbol table */
6685 dynsym
= new_section(".dynsym", SHT_DYNSYM
, SHF_ALLOC
);
6686 dynsym
->sh_entsize
= sizeof(Elf32_Sym
);
6687 dynstr
= new_section(".dynstr", SHT_STRTAB
, SHF_ALLOC
);
6688 put_elf_str(dynstr
, "");
6689 dynsym
->link
= dynstr
;
6690 put_elf_sym(dynsym
, 0, 0, 0, 0, 0, NULL
);
6693 hash
= new_section_hash(".hash", SHF_ALLOC
,
6694 ELF_DYNSYM_HASH_SIZE
, dynsym
);
6696 /* add dynamic section */
6697 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
6698 SHF_ALLOC
| SHF_WRITE
);
6699 dynamic
->link
= dynstr
;
6700 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
6702 /* add PLT and GOT */
6703 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6704 plt
->sh_entsize
= 4;
6705 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6706 got
->sh_entsize
= 4;
6708 /* add undefined symbols in dynamic symbol table */
6710 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6711 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6713 if (sym
->st_shndx
== SHN_UNDEF
) {
6714 name
= symtab_section
->link
->data
+ sym
->st_name
;
6715 type
= ELF32_ST_TYPE(sym
->st_info
);
6716 put_elf_sym(dynsym
, 0, 0,
6717 sym
->st_info
, 0, SHN_UNDEF
, name
);
6718 if (type
== STT_FUNC
) {
6720 /* prepare space for relocation */
6721 put_elf_reloc(dynsym
, got
, 0, 0, 0);
6726 /* update PLT/GOT sizes so that we can allocate their space */
6727 plt
->data_ptr
+= 16 * (nb_plt_entries
+ 1);
6728 got
->data_ptr
+= 4 * (nb_plt_entries
+ 3);
6730 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, "libc.so.6"));
6731 /* XXX: add other libs */
6733 /* add necessary space for other entries */
6734 saved_dynamic_data_ptr
= dynamic
->data_ptr
;
6735 dynamic
->data_ptr
+= 8 * 9;
6738 sort_symbols(symtab_section
);
6740 memset(&ehdr
, 0, sizeof(ehdr
));
6742 /* we add a section for symbols */
6743 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
6744 put_elf_str(strsec
, "");
6746 /* compute number of sections */
6747 shnum
= nb_sections
;
6749 /* this array is used to reorder sections in the output file */
6750 section_order
= malloc(sizeof(int) * shnum
);
6752 error("memory full");
6753 section_order
[0] = 0;
6756 /* compute number of program headers */
6773 /* allocate strings for section names */
6774 for(i
= 1; i
< nb_sections
; i
++) {
6776 s
->sh_name
= put_elf_str(strsec
, s
->name
);
6777 s
->sh_size
= s
->data_ptr
- s
->data
;
6780 /* allocate program segment headers */
6781 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
6783 error("memory full");
6784 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
6786 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6788 /* compute section to program header mapping */
6789 if (file_type
== TCC_FILE_DLL
)
6792 addr
= ELF_START_ADDR
;
6794 /* compute address after headers */
6795 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
6797 /* leave one program header for the program interpreter */
6802 for(j
= 0; j
< 2; j
++) {
6803 ph
->p_type
= PT_LOAD
;
6805 ph
->p_flags
= PF_R
| PF_X
;
6807 ph
->p_flags
= PF_R
| PF_W
;
6808 ph
->p_align
= ELF_PAGE_SIZE
;
6810 for(i
= 1; i
< nb_sections
; i
++) {
6812 /* compute if section should be included */
6814 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
6818 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
6819 (SHF_ALLOC
| SHF_WRITE
))
6822 section_order
[sh_order_index
++] = i
;
6824 /* section matches: we align it and add its size */
6826 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
6827 ~(s
->sh_addralign
- 1);
6828 s
->sh_offset
= file_offset
;
6829 addr
+= file_offset
- tmp
;
6832 if (ph
->p_offset
== 0) {
6833 ph
->p_offset
= file_offset
;
6835 ph
->p_paddr
= ph
->p_vaddr
;
6838 if (s
->sh_type
!= SHT_NOBITS
)
6839 file_offset
+= s
->sh_size
;
6841 ph
->p_filesz
= file_offset
- ph
->p_offset
;
6842 ph
->p_memsz
= addr
- ph
->p_vaddr
;
6846 /* if interpreter, then add corresponing program header */
6850 ph
->p_type
= PT_INTERP
;
6851 ph
->p_offset
= interp
->sh_offset
;
6852 ph
->p_vaddr
= interp
->sh_addr
;
6853 ph
->p_paddr
= ph
->p_vaddr
;
6854 ph
->p_filesz
= interp
->sh_size
;
6855 ph
->p_memsz
= interp
->sh_size
;
6857 ph
->p_align
= interp
->sh_addralign
;
6860 /* if dynamic section, then add corresponing program header */
6862 int sym_index
, plt_offset
;
6865 ph
= &phdr
[phnum
- 1];
6867 ph
->p_type
= PT_DYNAMIC
;
6868 ph
->p_offset
= dynamic
->sh_offset
;
6869 ph
->p_vaddr
= dynamic
->sh_addr
;
6870 ph
->p_paddr
= ph
->p_vaddr
;
6871 ph
->p_filesz
= dynamic
->sh_size
;
6872 ph
->p_memsz
= dynamic
->sh_size
;
6873 ph
->p_flags
= PF_R
| PF_W
;
6874 ph
->p_align
= dynamic
->sh_addralign
;
6876 /* now all the sections are mapped, so we can compute all
6879 /* first three got entries */
6880 got
->data_ptr
= got
->data
;
6881 plt
->data_ptr
= plt
->data
;
6883 got
->reloc
->data_ptr
= got
->reloc
->data
;
6885 put32(got
->data_ptr
, dynamic
->sh_addr
);
6887 put32(got
->data_ptr
, 0);
6889 put32(got
->data_ptr
, 0);
6892 /* first plt entry */
6894 p
[0] = 0xff; /* pushl got + 4 */
6896 put32(p
+ 2, got
->sh_addr
+ 4);
6897 p
[6] = 0xff; /* jmp *(got + 8) */
6899 put32(p
+ 8, got
->sh_addr
+ 8);
6900 plt
->data_ptr
+= 16;
6902 /* add undefined symbols in dynamic symbol table. also update
6903 PLT and GOT if needed */
6906 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
6907 sym
< (Elf32_Sym
*)dynsym
->data_ptr
;
6909 type
= ELF32_ST_TYPE(sym
->st_info
);
6910 if (type
== STT_FUNC
) {
6911 /* one more entry in PLT */
6913 p
[0] = 0xff; /* jmp *(got + x) */
6915 put32(p
+ 2, got
->sh_addr
+ got
->data_ptr
- got
->data
);
6916 p
[6] = 0x68; /* push $xxx */
6917 put32(p
+ 7, plt_offset
);
6918 p
[11] = 0xe9; /* jmp plt_start */
6919 put32(p
+ 12, -(plt
->data_ptr
+ 16 - plt
->data
));
6921 /* patch symbol value to point to plt */
6922 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
6925 plt
->data_ptr
+= 16;
6927 /* corresponding got entry */
6928 put_elf_reloc(dynsym
, got
,
6929 got
->sh_addr
+ got
->data_ptr
- got
->data
,
6932 put32(got
->data_ptr
, 0);
6937 /* put dynamic section entries */
6939 dynamic
->data_ptr
= saved_dynamic_data_ptr
;
6940 put_dt(dynamic
, DT_HASH
, hash
->sh_addr
);
6941 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
6942 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
6943 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_ptr
- dynstr
->data
);
6944 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
6945 put_dt(dynamic
, DT_REL
, got
->reloc
->sh_addr
);
6946 put_dt(dynamic
, DT_RELSZ
, got
->reloc
->data_ptr
- got
->reloc
->data
);
6947 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
6948 put_dt(dynamic
, DT_NULL
, 0);
6951 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
6952 ehdr
.e_phnum
= phnum
;
6953 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
6956 /* all other sections come after */
6957 for(i
= 1; i
< nb_sections
; i
++) {
6959 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
6961 section_order
[sh_order_index
++] = i
;
6963 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
6964 ~(s
->sh_addralign
- 1);
6965 s
->sh_offset
= file_offset
;
6966 if (s
->sh_type
!= SHT_NOBITS
)
6967 file_offset
+= s
->sh_size
;
6971 /* if building executable, then relocate each section except the GOT
6972 which is already relocated */
6973 if (file_type
== TCC_FILE_EXE
) {
6974 for(i
= 1; i
< nb_sections
; i
++) {
6976 if (s
->reloc
&& s
!= got
)
6977 relocate_section(s
);
6983 file_offset
= (file_offset
+ 3) & -4;
6986 ehdr
.e_ident
[0] = ELFMAG0
;
6987 ehdr
.e_ident
[1] = ELFMAG1
;
6988 ehdr
.e_ident
[2] = ELFMAG2
;
6989 ehdr
.e_ident
[3] = ELFMAG3
;
6990 ehdr
.e_ident
[4] = ELFCLASS32
;
6991 ehdr
.e_ident
[5] = ELFDATA2LSB
;
6992 ehdr
.e_ident
[6] = EV_CURRENT
;
6996 ehdr
.e_type
= ET_EXEC
;
6999 ehdr
.e_type
= ET_DYN
;
7002 ehdr
.e_type
= ET_REL
;
7005 ehdr
.e_machine
= EM_386
;
7006 ehdr
.e_version
= EV_CURRENT
;
7007 ehdr
.e_entry
= 0; /* XXX: patch it */
7008 ehdr
.e_shoff
= file_offset
;
7009 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
7010 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
7011 ehdr
.e_shnum
= shnum
;
7012 ehdr
.e_shstrndx
= shnum
- 1;
7014 /* write elf file */
7015 if (file_type
== TCC_FILE_OBJ
)
7019 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
7021 error("could not write '%s'", filename
);
7023 f
= fdopen(fd
, "w");
7024 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
7025 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
7026 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7027 for(i
=1;i
<nb_sections
;i
++) {
7028 s
= sections
[section_order
[i
]];
7029 if (s
->sh_type
!= SHT_NOBITS
) {
7030 while (offset
< s
->sh_offset
) {
7034 size
= s
->data_ptr
- s
->data
;
7035 fwrite(s
->data
, 1, size
, f
);
7039 while (offset
< ehdr
.e_shoff
) {
7044 /* output section headers */
7045 for(i
=0;i
<nb_sections
;i
++) {
7047 memset(sh
, 0, sizeof(Elf32_Shdr
));
7050 sh
->sh_name
= s
->sh_name
;
7051 sh
->sh_type
= s
->sh_type
;
7052 sh
->sh_flags
= s
->sh_flags
;
7053 sh
->sh_entsize
= s
->sh_entsize
;
7054 sh
->sh_info
= s
->sh_info
;
7056 sh
->sh_link
= s
->link
->sh_num
;
7057 sh
->sh_addralign
= s
->sh_addralign
;
7058 sh
->sh_addr
= s
->sh_addr
;
7059 sh
->sh_offset
= s
->sh_offset
;
7060 sh
->sh_size
= s
->sh_size
;
7062 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
7066 free(section_order
);
7071 typedef struct SectionMergeInfo
{
7072 Section
*s
; /* corresponding existing section */
7073 unsigned long offset
; /* offset of the new section in the existing section */
7074 int new_section
; /* true if section 's' was added */
7077 /* load an object file and merge it with current files */
7078 /* XXX: handle correctly stab (debug) info */
7079 int tcc_load_object(TCCState
*s1
, const char *filename
)
7083 Elf32_Shdr
*shdr
, *sh
;
7084 int size
, i
, j
, offset
, offsetl
, offseti
;
7085 unsigned char *strsec
;
7087 SectionMergeInfo
*sm_table
, *sm
;
7092 f
= fopen(filename
, "r");
7094 error("could not open '%s'", filename
);
7095 if (fread(&ehdr
, 1, sizeof(ehdr
), f
) != sizeof(ehdr
))
7097 if (ehdr
.e_ident
[0] != ELFMAG0
||
7098 ehdr
.e_ident
[1] != ELFMAG1
||
7099 ehdr
.e_ident
[2] != ELFMAG2
||
7100 ehdr
.e_ident
[3] != ELFMAG3
)
7102 /* test if object file */
7103 if (ehdr
.e_type
!= ET_REL
)
7105 /* test CPU specific stuff */
7106 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7107 ehdr
.e_machine
!= EM_386
) {
7109 error("invalid object file '%s'", filename
);
7112 size
= sizeof(Elf32_Shdr
) * ehdr
.e_shnum
;
7113 shdr
= malloc(size
);
7115 error("memory full");
7116 fseek(f
, ehdr
.e_shoff
, SEEK_SET
);
7117 if (fread(shdr
, 1, size
, f
) != size
)
7120 sm_table
= malloc(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7122 error("memory full");
7123 memset(sm_table
, 0, sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7125 /* load section names */
7126 sh
= &shdr
[ehdr
.e_shstrndx
];
7127 strsec
= malloc(sh
->sh_size
);
7129 error("memory full");
7130 fseek(f
, sh
->sh_offset
, SEEK_SET
);
7131 fread(strsec
, 1, sh
->sh_size
, f
);
7133 /* now examine each section and try to merge its content with the
7135 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7136 /* no need to examine section name strtab */
7137 if (i
== ehdr
.e_shstrndx
)
7140 sh_name
= strsec
+ sh
->sh_name
;
7141 printf("%d: sh_name=%s\n", i
, sh_name
);
7142 /* ignore sections types we do not handle */
7143 if (sh
->sh_type
!= SHT_PROGBITS
&&
7144 sh
->sh_type
!= SHT_SYMTAB
&&
7145 sh
->sh_type
!= SHT_STRTAB
&&
7146 sh
->sh_type
!= SHT_REL
&&
7147 sh
->sh_type
!= SHT_NOBITS
)
7149 if (sh
->sh_addralign
< 1)
7150 sh
->sh_addralign
= 1;
7151 /* find corresponding section, if any */
7152 for(j
= 1; j
< nb_sections
;j
++) {
7154 if (!strcmp(s
->name
, sh_name
))
7157 /* not found: create new section */
7158 s
= new_section(sh_name
, sh
->sh_type
, sh
->sh_flags
);
7159 /* take as much info as possible from the section. sh_link and
7160 sh_info will be updated later */
7161 s
->sh_addralign
= sh
->sh_addralign
;
7162 s
->sh_entsize
= sh
->sh_entsize
;
7163 sm_table
[i
].new_section
= 1;
7165 if (sh
->sh_type
!= s
->sh_type
)
7167 if (sh
->sh_type
== SHT_SYMTAB
) {
7168 /* if symbol, suppress first dummy entry */
7169 sh
->sh_size
-= sizeof(Elf32_Sym
);
7170 sh
->sh_offset
+= sizeof(Elf32_Sym
);
7173 /* align start of section */
7174 offset
= s
->data_ptr
- s
->data
;
7175 size
= sh
->sh_addralign
- 1;
7176 offset
= (offset
+ size
) & ~size
;
7177 if (sh
->sh_addralign
> s
->sh_addralign
)
7178 s
->sh_addralign
= sh
->sh_addralign
;
7179 s
->data_ptr
= s
->data
+ offset
;
7180 sm_table
[i
].offset
= offset
;
7182 /* concatenate sections */
7184 if (sh
->sh_type
!= SHT_NOBITS
) {
7185 fseek(f
, sh
->sh_offset
, SEEK_SET
);
7186 fread(s
->data_ptr
, 1, size
, f
);
7188 s
->data_ptr
+= size
;
7191 /* second short pass to update sh_link and sh_info fields of new
7194 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7196 if (!s
|| !sm_table
[i
].new_section
)
7199 if (sh
->sh_link
> 0)
7200 s
->link
= sm_table
[sh
->sh_link
].s
;
7201 if (sh
->sh_type
== SHT_REL
) {
7202 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
7203 /* update backward link */
7204 sections
[s
->sh_info
]->reloc
= s
;
7208 /* third pass to patch symbol and relocation entries */
7209 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7214 offset
= sm_table
[i
].offset
;
7215 switch(s
->sh_type
) {
7217 /* take strtab offset information */
7218 sl
= sm_table
[sh
->sh_link
].s
;
7219 offsetl
= sm_table
[sh
->sh_link
].offset
;
7221 for(sym
= (Elf32_Sym
*)(s
->data
+ offset
);
7222 sym
< (Elf32_Sym
*)s
->data_ptr
;
7225 if (sym
->st_name
!= 0)
7226 sym
->st_name
+= offsetl
;
7227 /* add to internal hash table */
7229 update_hash_elf_sym(s
->hash
, sym
- (Elf32_Sym
*)s
->data
,
7230 sym
->st_info
, sl
->data
+ sym
->st_name
);
7232 /* no need to patch */
7233 if (sym
->st_shndx
== SHN_UNDEF
||
7234 sym
->st_shndx
>= SHN_LORESERVE
)
7236 /* transform section number */
7237 sm
= &sm_table
[sym
->st_shndx
];
7239 sym
->st_shndx
= sm
->s
->sh_num
;
7241 sym
->st_value
+= sm
->offset
;
7243 /* if the section was suppressed, we put a dummy symbol */
7244 /* XXX: suppress it ? */
7246 sym
->st_shndx
= SHN_ABS
;
7249 printf("warning: invalid symbol %d\n",
7250 sym
- (Elf32_Sym
*)(s
->data
+ offset
) + 1);
7255 /* take symbol offset information */
7256 /* minus one because we deleted the first symbol */
7257 offsetl
= (sm_table
[sh
->sh_link
].offset
/ sizeof(Elf32_Sym
)) - 1;
7258 /* take relocation offset information */
7259 offseti
= sm_table
[sh
->sh_info
].offset
;
7261 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
7262 rel
< (Elf32_Rel
*)s
->data_ptr
;
7264 int type
, sym_index
;
7265 /* offset symbol index */
7266 type
= ELF32_R_TYPE(rel
->r_info
);
7267 sym_index
= ELF32_R_SYM(rel
->r_info
);
7268 sym_index
+= offsetl
;
7269 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
7270 /* offset the relocation offset */
7271 rel
->r_offset
+= offseti
;
7284 /* print the position in the source file of PC value 'pc' by reading
7285 the stabs debug information */
7286 static void rt_printline(unsigned long wanted_pc
)
7288 Stab_Sym
*sym
, *sym_end
;
7289 char func_name
[128];
7290 unsigned long func_addr
, last_pc
, pc
;
7291 const char *incl_files
[INCLUDE_STACK_SIZE
];
7292 int incl_index
, len
, last_line_num
, i
;
7293 const char *str
, *p
;
7295 func_name
[0] = '\0';
7298 last_pc
= 0xffffffff;
7300 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7301 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
7302 while (sym
< sym_end
) {
7303 switch(sym
->n_type
) {
7304 /* function start or end */
7306 if (sym
->n_strx
== 0) {
7307 func_name
[0] = '\0';
7310 str
= stabstr_section
->data
+ sym
->n_strx
;
7311 p
= strchr(str
, ':');
7313 pstrcpy(func_name
, sizeof(func_name
), str
);
7316 if (len
> sizeof(func_name
) - 1)
7317 len
= sizeof(func_name
) - 1;
7318 memcpy(func_name
, str
, len
);
7319 func_name
[len
] = '\0';
7321 func_addr
= sym
->n_value
;
7324 /* line number info */
7326 pc
= sym
->n_value
+ func_addr
;
7327 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7330 last_line_num
= sym
->n_desc
;
7334 str
= stabstr_section
->data
+ sym
->n_strx
;
7336 if (incl_index
< INCLUDE_STACK_SIZE
) {
7337 incl_files
[incl_index
++] = str
;
7345 if (sym
->n_strx
== 0) {
7346 incl_index
= 0; /* end of translation unit */
7348 str
= stabstr_section
->data
+ sym
->n_strx
;
7349 /* do not add path */
7351 if (len
> 0 && str
[len
- 1] != '/')
7358 /* did not find line number info: */
7359 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
7362 for(i
= 0; i
< incl_index
- 1; i
++)
7363 fprintf(stderr
, "In file included from %s\n",
7365 if (incl_index
> 0) {
7366 fprintf(stderr
, "%s:%d: ",
7367 incl_files
[incl_index
- 1], last_line_num
);
7369 if (func_name
[0] != '\0') {
7370 fprintf(stderr
, "in function '%s()': ", func_name
);
7374 /* emit a run time error at position 'pc' */
7375 void rt_error(unsigned long pc
, const char *fmt
, ...)
7381 vfprintf(stderr
, fmt
, ap
);
7382 fprintf(stderr
, "\n");
7388 /* signal handler for fatal errors */
7389 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7391 struct ucontext
*uc
= puc
;
7395 pc
= uc
->uc_mcontext
.gregs
[14];
7397 #error please put the right sigcontext field
7402 switch(siginf
->si_code
) {
7405 rt_error(pc
, "division by zero");
7408 rt_error(pc
, "floating point exception");
7414 rt_error(pc
, "dereferencing invalid pointer");
7417 rt_error(pc
, "illegal instruction");
7420 rt_error(pc
, "abort() called");
7423 rt_error(pc
, "caught signal %d", signum
);
7430 static void *resolve_sym(const char *sym
)
7432 #ifdef CONFIG_TCC_BCHECK
7433 if (do_bounds_check
) {
7435 ptr
= bound_resolve_sym(sym
);
7440 return dlsym(NULL
, sym
);
7443 static void resolve_extern_syms(void)
7449 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7450 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
7452 if (sym
->st_shndx
== SHN_UNDEF
) {
7453 name
= symtab_section
->link
->data
+ sym
->st_name
;
7454 addr
= (unsigned long)resolve_sym(name
);
7456 error("unresolved external reference '%s'", name
);
7457 sym
->st_value
= addr
;
7458 sym
->st_shndx
= SHN_ABS
;
7463 /* relocate all the code and data */
7464 static void relocate_program(void)
7468 /* compute relocation address : section are relocated in place */
7469 for(s
= first_section
; s
!= NULL
; s
= s
->next
) {
7470 if (s
->sh_flags
& SHF_ALLOC
)
7471 s
->sh_addr
= (unsigned long)s
->data
;
7474 /* relocate each section */
7475 for(s
= first_section
; s
!= NULL
; s
= s
->next
) {
7476 if ((s
->sh_flags
& SHF_ALLOC
) && s
->reloc
)
7477 relocate_section(s
);
7481 /* launch the compiled program with the given arguments */
7482 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7484 int (*prog_main
)(int, char **);
7487 resolve_extern_syms();
7491 sym_index
= find_elf_sym(symtab_section
, "main");
7493 error("main() not defined");
7494 prog_main
= (void *)get_sym_val(sym_index
);
7498 error("debug mode currently not available for Windows");
7500 struct sigaction sigact
;
7501 /* install TCC signal handlers to print debug info on fatal
7503 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7504 sigact
.sa_sigaction
= sig_error
;
7505 sigemptyset(&sigact
.sa_mask
);
7506 sigaction(SIGFPE
, &sigact
, NULL
);
7507 sigaction(SIGILL
, &sigact
, NULL
);
7508 sigaction(SIGSEGV
, &sigact
, NULL
);
7509 sigaction(SIGBUS
, &sigact
, NULL
);
7510 sigaction(SIGABRT
, &sigact
, NULL
);
7514 #ifdef CONFIG_TCC_BCHECK
7515 if (do_bounds_check
) {
7518 /* add all known static regions */
7519 p
= (int *)bounds_section
->data
;
7520 p_end
= (int *)bounds_section
->data_ptr
;
7522 __bound_new_region((void *)p
[0], p
[1]);
7528 return (*prog_main
)(argc
, argv
);
7531 TCCState
*tcc_new(void)
7536 s
= malloc(sizeof(TCCState
));
7540 /* default include paths */
7541 nb_include_paths
= 0;
7542 tcc_add_include_path(s
, "/usr/include");
7543 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7545 /* add all tokens */
7546 tok_ident
= TOK_IDENT
;
7551 tok_alloc(p
, r
- p
- 1);
7555 /* standard defines */
7556 tcc_define_symbol(s
, "__STDC__", NULL
);
7558 tcc_define_symbol(s
, "__i386__", NULL
);
7560 /* tiny C specific defines */
7561 tcc_define_symbol(s
, "__TINYC__", NULL
);
7563 /* create standard sections */
7565 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7566 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7567 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
7569 /* symbols are always generated for linking stage */
7570 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
7571 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
7572 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
7573 put_elf_str(strtab_section
, "");
7574 symtab_section
->link
= strtab_section
;
7575 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
7577 /* private hash table for extern symbols */
7578 new_section_hash(".hashtab", SHF_PRIVATE
,
7579 ELF_SYM_HASH_SIZE
, symtab_section
);
7583 void tcc_delete(TCCState
*s
)
7588 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
7592 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
7594 pathname1
= strdup(pathname
);
7597 include_paths
[nb_include_paths
++] = pathname1
;
7601 #if !defined(LIBTCC)
7603 void tcc_add_file(TCCState
*s
, const char *filename
)
7608 /* find file type with extension */
7609 p
= strrchr(filename
, '.');
7615 tcc_load_object(s
, filename
);
7617 tcc_compile_file(s
, filename
);
7623 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7624 "usage: tcc [-c] [-o outfile] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7625 " [-g] [-b] [-llib] [-shared] [-static]\n"
7626 " [--] infile1 [infile2... --] [infile_args...]\n"
7628 "General options:\n"
7629 " -c compile only - generate an object file\n"
7630 " -i infile compile infile\n"
7631 " -o outfile set output filename (NOT WORKING YET)\n"
7632 " -bench output compilation statistics\n"
7633 " -- allows multiples input files if no -o option given. Also\n"
7634 " separate input files from runtime arguments\n"
7635 "Preprocessor options:\n"
7636 " -Idir add include path 'dir'\n"
7637 " -Dsym[=val] define 'sym' with value 'val'\n"
7638 " -Usym undefine 'sym'\n"
7639 "C compiler options:\n"
7640 " -g generate runtime debug info\n"
7641 #ifdef CONFIG_TCC_BCHECK
7642 " -b compile with built-in memory and bounds checker (implies -g)\n"
7645 " -llib link with dynamic library 'lib'\n"
7646 " -shared generate a shared library (NOT WORKING YET)\n"
7647 " -static static linking (NOT WORKING YET)\n"
7651 int main(int argc
, char **argv
)
7654 int optind
, file_type
, multiple_files
;
7658 file_type
= TCC_FILE_EXE
;
7664 if (optind
>= argc
) {
7674 /* '--' enables multiple files input */
7676 } else if (r
[1] == 'I') {
7677 if (tcc_add_include_path(s
, r
+ 2) < 0)
7678 error("too many include paths");
7679 } else if (r
[1] == 'D') {
7682 value
= strchr(sym
, '=');
7687 tcc_define_symbol(s
, sym
, value
);
7688 } else if (r
[1] == 'U') {
7689 tcc_undefine_symbol(s
, r
+ 2);
7690 } else if (r
[1] == 'l') {
7692 snprintf(buf
, sizeof(buf
), "lib%s.so", r
+ 2);
7693 tcc_add_dll(s
, buf
);
7694 } else if (!strcmp(r
+ 1, "bench")) {
7696 #ifdef CONFIG_TCC_BCHECK
7697 } else if (r
[1] == 'b') {
7698 if (!do_bounds_check
) {
7699 do_bounds_check
= 1;
7701 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7702 /* create bounds sections */
7703 bounds_section
= new_section(".bounds",
7704 SHT_PROGBITS
, SHF_ALLOC
);
7705 lbounds_section
= new_section(".lbounds",
7706 SHT_PROGBITS
, SHF_ALLOC
);
7707 /* debug is implied */
7711 } else if (r
[1] == 'g') {
7712 #ifdef CONFIG_TCC_BCHECK
7719 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
7720 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7721 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
7722 put_elf_str(stabstr_section
, "");
7723 stab_section
->link
= stabstr_section
;
7724 /* put first entry */
7725 put_stabs("", 0, 0, 0, 0);
7728 /* the following options are only for testing, so not
7732 file_type
= TCC_FILE_OBJ
;
7733 } else if (!strcmp(r
+ 1, "static")) {
7735 } else if (!strcmp(r
+ 1, "shared")) {
7736 file_type
= TCC_FILE_DLL
;
7737 } else if (r
[1] == 'o') {
7741 outfile
= argv
[optind
++];
7743 error("invalid option -- '%s'", r
);
7747 tcc_add_file(s
, argv
[optind
]);
7748 if (multiple_files
) {
7749 while ((optind
+ 1) < argc
) {
7754 error("'--' expected");
7762 printf("total: %d idents, %d lines, %d bytes\n",
7763 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7767 tcc_output_file(s
, outfile
, file_type
);
7770 return tcc_run(s
, argc
- optind
, argv
+ optind
);