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