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