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.
31 #include <sys/ucontext.h>
36 #ifndef CONFIG_TCC_STATIC
43 /* preprocessor debug */
46 /* target selection */
47 //#define TCC_TARGET_I386 /* i386 code generator */
48 //#define TCC_TARGET_IL /* .NET CLI generator */
50 /* default target is I386 */
51 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
52 #define TCC_TARGET_I386
55 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
56 #define CONFIG_TCC_BCHECK /* enable bound checking code */
59 #ifndef CONFIG_TCC_PREFIX
60 #define CONFIG_TCC_PREFIX "/usr/local"
63 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
64 executables or dlls */
65 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
67 /* amount of virtual memory associated to a section (currently, we do
69 #define SECTION_VSIZE (1024 * 1024)
71 #define INCLUDE_STACK_SIZE 32
72 #define IFDEF_STACK_SIZE 64
73 #define VSTACK_SIZE 64
74 #define STRING_MAX_SIZE 1024
76 #define TOK_HASH_SIZE 2048 /* must be a power of two */
77 #define TOK_ALLOC_INCR 512 /* must be a power of two */
78 #define SYM_HASH_SIZE 1031
79 #define ELF_SYM_HASH_SIZE 2048
80 #define ELF_DYNSYM_HASH_SIZE 32
82 /* token symbol management */
83 typedef struct TokenSym
{
84 struct TokenSym
*hash_next
;
85 int tok
; /* token number */
91 typedef union CValue
{
97 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
99 unsigned long long ull
;
107 typedef struct SValue
{
109 unsigned short r
; /* register + flags */
110 unsigned short r2
; /* second register, used for 'long long'
111 type. If not used, set to VT_CONST */
112 CValue c
; /* constant, if VT_CONST */
115 /* symbol management */
117 int v
; /* symbol token */
118 int t
; /* associated type */
119 int r
; /* associated register */
120 int c
; /* associated number */
121 struct Sym
*next
; /* next related symbol */
122 struct Sym
*prev
; /* prev symbol in stack */
123 struct Sym
*hash_next
; /* next symbol in hash table */
126 typedef struct SymStack
{
128 struct Sym
*hash
[SYM_HASH_SIZE
];
131 /* section definition */
132 /* XXX: use directly ELF structure for parameters ? */
133 /* special flag to indicate that the section should not be linked to
135 #define SHF_PRIVATE 0x80000000
137 typedef struct Section
{
138 unsigned long data_offset
; /* current data offset */
139 unsigned char *data
; /* section data */
140 int sh_name
; /* elf section name (only used during output) */
141 int sh_num
; /* elf section number */
142 int sh_type
; /* elf section type */
143 int sh_flags
; /* elf section flags */
144 int sh_info
; /* elf section info */
145 int sh_addralign
; /* elf section alignment */
146 int sh_entsize
; /* elf entry size */
147 unsigned long sh_size
; /* section size (only used during output) */
148 unsigned long sh_addr
; /* address at which the section is relocated */
149 unsigned long sh_offset
; /* address at which the section is relocated */
150 struct Section
*link
; /* link to another section */
151 struct Section
*reloc
; /* corresponding section for relocation, if any */
152 struct Section
*hash
; /* hash table for symbols */
153 struct Section
*next
;
154 char name
[64]; /* section name */
157 typedef struct DLLReference
{
162 /* GNUC attribute definition */
163 typedef struct AttributeDef
{
166 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
169 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
170 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
171 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
173 /* stored in 'Sym.c' field */
174 #define FUNC_NEW 1 /* ansi function prototype */
175 #define FUNC_OLD 2 /* old function prototype */
176 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
178 /* stored in 'Sym.r' field */
179 #define FUNC_CDECL 0 /* standard c call */
180 #define FUNC_STDCALL 1 /* pascal c call */
182 /* field 'Sym.t' for macros */
183 #define MACRO_OBJ 0 /* object like macro */
184 #define MACRO_FUNC 1 /* function like macro */
186 /* field 'Sym.t' for labels */
187 #define LABEL_FORWARD 1 /* label is forward defined */
189 /* type_decl() types */
190 #define TYPE_ABSTRACT 1 /* type without variable */
191 #define TYPE_DIRECT 2 /* type with variable */
193 #define IO_BUF_SIZE 8192
195 typedef struct BufferedFile
{
196 unsigned char *buf_ptr
;
197 unsigned char *buf_end
;
199 int line_num
; /* current line number - here to simply code */
200 char filename
[1024]; /* current filename - here to simplify code */
201 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
204 #define CH_EOB 0 /* end of buffer or '\0' char in file */
205 #define CH_EOF (-1) /* end of file */
207 /* parsing state (used to save parser state to reparse part of the
208 source several times) */
209 typedef struct ParseState
{
216 /* used to record tokens */
217 typedef struct TokenString
{
224 struct BufferedFile
*file
;
225 int ch
, ch1
, tok
, tok1
;
227 int return_linefeed
; /* if true, line feed is returned as a token */
231 int nb_sections
; /* number of sections, including first dummy section */
232 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
233 Section
*cur_text_section
; /* current section where function code is
235 /* bound check related sections */
236 Section
*bounds_section
; /* contains global data bound description */
237 Section
*lbounds_section
; /* contains local data bound description */
238 /* symbol sections */
239 Section
*symtab_section
, *strtab_section
;
240 /* temporary dynamic symbol sections (for dll loading) */
241 Section
*dynsymtab_section
, *dynstrtab_section
;
242 /* exported dynamic symbol section */
246 unsigned long *got_offsets
;
251 /* array of all loaded dlls (including those referenced by loaded
253 DLLReference
**loaded_dlls
;
257 Section
*stab_section
, *stabstr_section
;
259 char **library_paths
;
260 int nb_library_paths
;
262 /* loc : local variable index
263 ind : output code index
265 anon_sym: anonymous symbol index
268 prog
, ind
, loc
, const_wanted
;
269 int global_expr
; /* true if compound literals must be allocated
270 globally (used during initializers parsing */
271 int func_vt
, func_vc
; /* current function return type (used by
272 return instruction) */
273 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
275 TokenSym
**table_ident
;
276 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
277 char token_buf
[STRING_MAX_SIZE
+ 1];
279 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
281 SValue vstack
[VSTACK_SIZE
], *vtop
;
282 int *macro_ptr
, *macro_ptr_allocated
;
283 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
284 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
285 char **include_paths
;
286 int nb_include_paths
;
287 int char_pointer_type
;
290 /* compile with debug symbol (and use them if error during execution) */
293 /* compile with built-in memory and bounds checker */
294 int do_bounds_check
= 0;
296 /* display benchmark infos */
301 /* use GNU C extensions */
304 /* use Tiny C extensions */
307 /* if true, static linking is performed */
310 /* give the path of the tcc libraries */
311 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
317 /* The current value can be: */
318 #define VT_VALMASK 0x00ff
319 #define VT_CONST 0x00f0 /* constant in vc
320 (must be first non register value) */
321 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
322 #define VT_LOCAL 0x00f2 /* offset on stack */
323 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
324 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
325 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
326 #define VT_LVAL 0x0100 /* var is an lvalue */
327 #define VT_SYM 0x0200 /* a symbol value is added */
328 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
329 char/short stored in integer registers) */
330 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
331 dereferencing value */
332 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
333 bounding function call point is in vc */
334 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
335 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
336 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
337 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
340 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
342 #define VT_INT 0 /* integer type */
343 #define VT_BYTE 1 /* signed byte type */
344 #define VT_SHORT 2 /* short type */
345 #define VT_VOID 3 /* void type */
346 #define VT_PTR 4 /* pointer */
347 #define VT_ENUM 5 /* enum definition */
348 #define VT_FUNC 6 /* function type */
349 #define VT_STRUCT 7 /* struct/union definition */
350 #define VT_FLOAT 8 /* IEEE float */
351 #define VT_DOUBLE 9 /* IEEE double */
352 #define VT_LDOUBLE 10 /* IEEE long double */
353 #define VT_BOOL 11 /* ISOC99 boolean type */
354 #define VT_LLONG 12 /* 64 bit integer */
355 #define VT_LONG 13 /* long integer (NEVER USED as type, only
357 #define VT_BTYPE 0x000f /* mask for basic type */
358 #define VT_UNSIGNED 0x0010 /* unsigned type */
359 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
360 #define VT_BITFIELD 0x0040 /* bitfield modifier */
363 #define VT_EXTERN 0x00000080 /* extern definition */
364 #define VT_STATIC 0x00000100 /* static variable */
365 #define VT_TYPEDEF 0x00000200 /* typedef definition */
367 /* type mask (except storage) */
368 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
372 /* warning: the following compare tokens depend on i386 asm code */
384 #define TOK_LAND 0xa0
388 #define TOK_MID 0xa3 /* inc/dec, to void constant */
390 #define TOK_UDIV 0xb0 /* unsigned division */
391 #define TOK_UMOD 0xb1 /* unsigned modulo */
392 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
393 #define TOK_CINT 0xb3 /* number in tokc */
394 #define TOK_CCHAR 0xb4 /* char constant in tokc */
395 #define TOK_STR 0xb5 /* pointer to string in tokc */
396 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
397 #define TOK_LCHAR 0xb7
398 #define TOK_LSTR 0xb8
399 #define TOK_CFLOAT 0xb9 /* float constant */
400 #define TOK_LINENUM 0xba /* line number info */
401 #define TOK_CDOUBLE 0xc0 /* double constant */
402 #define TOK_CLDOUBLE 0xc1 /* long double constant */
403 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
404 #define TOK_ADDC1 0xc3 /* add with carry generation */
405 #define TOK_ADDC2 0xc4 /* add with carry use */
406 #define TOK_SUBC1 0xc5 /* add with carry generation */
407 #define TOK_SUBC2 0xc6 /* add with carry use */
408 #define TOK_CUINT 0xc8 /* unsigned int constant */
409 #define TOK_CLLONG 0xc9 /* long long constant */
410 #define TOK_CULLONG 0xca /* unsigned long long constant */
411 #define TOK_ARROW 0xcb
412 #define TOK_DOTS 0xcc /* three dots */
413 #define TOK_SHR 0xcd /* unsigned shift right */
415 #define TOK_SHL 0x01 /* shift left */
416 #define TOK_SAR 0x02 /* signed shift right */
418 /* assignement operators : normal operator or 0x80 */
419 #define TOK_A_MOD 0xa5
420 #define TOK_A_AND 0xa6
421 #define TOK_A_MUL 0xaa
422 #define TOK_A_ADD 0xab
423 #define TOK_A_SUB 0xad
424 #define TOK_A_DIV 0xaf
425 #define TOK_A_XOR 0xde
426 #define TOK_A_OR 0xfc
427 #define TOK_A_SHL 0x81
428 #define TOK_A_SAR 0x82
430 #define TOK_EOF (-1) /* end of file */
431 #define TOK_LINEFEED 10 /* line feed */
433 /* all identificators and strings have token above that */
434 #define TOK_IDENT 256
455 /* ignored types Must have contiguous values */
461 TOK___SIGNED__
, /* gcc keyword */
464 TOK___INLINE__
, /* gcc keyword */
467 /* unsupported type */
481 /* preprocessor only */
482 TOK_UIDENT
, /* first "user" ident (not keyword) */
483 TOK_DEFINE
= TOK_UIDENT
,
499 /* special identifiers */
502 #define DEF(id, str) id,
508 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
509 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
510 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
511 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
512 "sizeof\0__attribute__\0"
513 /* the following are not keywords. They are included to ease parsing */
514 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
515 "defined\0undef\0error\0line\0"
516 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
518 /* builtin functions */
519 #define DEF(id, str) str "\0"
525 #define snprintf _snprintf
528 #if defined(WIN32) || defined(TCC_UCLIBC)
529 /* currently incorrect */
530 long double strtold(const char *nptr
, char **endptr
)
532 return (long double)strtod(nptr
, endptr
);
534 float strtof(const char *nptr
, char **endptr
)
536 return (float)strtod(nptr
, endptr
);
539 /* XXX: need to define this to use them in non ISOC99 context */
540 extern float strtof (const char *__nptr
, char **__endptr
);
541 extern long double strtold (const char *__nptr
, char **__endptr
);
544 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
545 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
549 void next_nomacro(void);
550 int expr_const(void);
554 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
555 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
558 void gv2(int rc1
, int rc2
);
559 void move_reg(int r
, int s
);
560 void save_regs(int n
);
561 void save_reg(int r
);
567 void macro_subst(TokenString
*tok_str
,
568 Sym
**nested_list
, int *macro_str
);
569 int save_reg_forced(int r
);
571 void force_charshort_cast(int t
);
572 void gen_cast(int t
);
574 Sym
*sym_find(int v
);
575 Sym
*sym_push(int v
, int t
, int r
, int c
);
578 int type_size(int t
, int *a
);
579 int pointed_type(int t
);
580 int pointed_size(int t
);
581 int is_compatible_types(int t1
, int t2
);
582 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
583 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
585 void error(const char *fmt
, ...);
586 void rt_error(unsigned long pc
, const char *fmt
, ...);
588 void vset(int t
, int r
, int v
);
589 void type_to_str(char *buf
, int buf_size
,
590 int t
, const char *varstr
);
591 char *get_tok_str(int v
, CValue
*cv
);
592 Sym
*external_sym(int v
, int u
, int r
);
593 static Sym
*get_sym_ref(int t
, Section
*sec
,
594 unsigned long offset
, unsigned long size
);
596 /* section generation */
597 static void *section_ptr(Section
*sec
, unsigned long size
);
598 static void *section_ptr_add(Section
*sec
, unsigned long size
);
599 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
);
600 void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
601 static int put_elf_str(Section
*s
, const char *sym
);
602 static int put_elf_sym(Section
*s
,
603 unsigned long value
, unsigned long size
,
604 int info
, int other
, int shndx
, const char *name
);
605 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
606 int type
, int symbol
);
607 static void put_stabs(const char *str
, int type
, int other
, int desc
,
608 unsigned long value
);
609 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
610 unsigned long value
, Section
*sec
, int sym_index
);
611 static void put_stabn(int type
, int other
, int desc
, int value
);
612 static void put_stabd(int type
, int other
, int desc
);
613 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
615 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
616 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
617 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
619 /* true if float/double/long double type */
620 static inline int is_float(int t
)
624 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
627 #ifdef TCC_TARGET_I386
628 #include "i386-gen.c"
634 #ifdef CONFIG_TCC_STATIC
636 #define RTLD_LAZY 0x001
637 #define RTLD_NOW 0x002
638 #define RTLD_GLOBAL 0x100
640 /* dummy function for profiling */
641 void *dlopen(const char *filename
, int flag
)
646 const char *dlerror(void)
651 typedef struct TCCSyms
{
656 #define TCCSYM(a) { #a, &a, },
658 /* add the symbol you want here if no dynamic linking is done */
659 static TCCSyms tcc_syms
[] = {
667 void *dlsym(void *handle
, const char *symbol
)
671 while (p
->str
!= NULL
) {
672 if (!strcmp(p
->str
, symbol
))
681 /********************************************************/
683 /* we use our own 'finite' function to avoid potential problems with
684 non standard math libs */
685 /* XXX: endianness dependant */
686 int ieee_finite(double d
)
689 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
692 /* copy a string and truncate it. */
693 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
700 q_end
= buf
+ buf_size
- 1;
712 /* strcat and truncate. */
713 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
718 pstrcpy(buf
+ len
, buf_size
- len
, s
);
722 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
729 /* every power of two we double array size */
730 if ((nb
& (nb
- 1)) == 0) {
735 pp
= realloc(pp
, nb_alloc
* sizeof(void *));
737 error("memory full");
744 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
749 sec
= malloc(sizeof(Section
));
751 error("memory full");
752 memset(sec
, 0, sizeof(Section
));
753 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
754 sec
->sh_type
= sh_type
;
755 sec
->sh_flags
= sh_flags
;
762 sec
->sh_addralign
= 4;
765 sec
->sh_addralign
= 1;
768 sec
->sh_addralign
= 32; /* default conservative alignment */
772 /* XXX: currently, a single malloc */
773 data
= malloc(SECTION_VSIZE
);
775 error("could not alloc section '%s'", name
);
777 data
= mmap(NULL
, SECTION_VSIZE
,
778 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
779 MAP_PRIVATE
| MAP_ANONYMOUS
,
781 if (data
== (void *)(-1))
782 error("could not mmap section '%s'", name
);
785 sec
->data_offset
= 0;
787 /* only add section if not private */
788 if (!(sh_flags
& SHF_PRIVATE
)) {
789 sec
->sh_num
= nb_sections
;
790 dynarray_add((void ***)§ions
, &nb_sections
, sec
);
795 /* reserve at least 'size' bytes in section 'sec' from sec->data_offset */
796 static void *section_ptr(Section
*sec
, unsigned long size
)
798 return sec
->data
+ sec
->data_offset
;
801 static void *section_ptr_add(Section
*sec
, unsigned long size
)
804 ptr
= sec
->data
+ sec
->data_offset
;
805 sec
->data_offset
+= size
;
809 /* return a reference to a section, and create it if it does not
811 Section
*find_section(const char *name
)
815 for(i
= 1; i
< nb_sections
; i
++) {
817 if (!strcmp(name
, sec
->name
))
820 /* sections are created as PROGBITS */
821 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
824 /* add a new relocation entry to symbol 'sym' in section 's' */
825 void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
828 put_extern_sym(sym
, NULL
, 0);
829 /* now we can add ELF relocation info */
830 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
833 static inline int isid(int c
)
835 return (c
>= 'a' && c
<= 'z') ||
836 (c
>= 'A' && c
<= 'Z') ||
840 static inline int isnum(int c
)
842 return c
>= '0' && c
<= '9';
845 static inline int toup(int c
)
847 if (ch
>= 'a' && ch
<= 'z')
848 return ch
- 'a' + 'A';
858 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
859 fprintf(stderr
, "In file included from %s:%d:\n",
860 (*f
)->filename
, (*f
)->line_num
);
861 if (file
->line_num
> 0) {
862 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
864 fprintf(stderr
, "%s: ", file
->filename
);
867 fprintf(stderr
, "tcc: ");
871 void error(const char *fmt
, ...)
876 vfprintf(stderr
, fmt
, ap
);
877 fprintf(stderr
, "\n");
882 void expect(const char *msg
)
884 error("%s expected", msg
);
887 void warning(const char *fmt
, ...)
893 fprintf(stderr
, "warning: ");
894 vfprintf(stderr
, fmt
, ap
);
895 fprintf(stderr
, "\n");
902 error("'%c' expected", c
);
906 void test_lvalue(void)
908 if (!(vtop
->r
& VT_LVAL
))
912 TokenSym
*tok_alloc(const char *str
, int len
)
914 TokenSym
*ts
, **pts
, **ptable
;
921 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
923 pts
= &hash_ident
[h
];
928 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
930 pts
= &(ts
->hash_next
);
933 if (tok_ident
>= SYM_FIRST_ANOM
)
934 error("memory full");
936 /* expand token table if needed */
937 i
= tok_ident
- TOK_IDENT
;
938 if ((i
% TOK_ALLOC_INCR
) == 0) {
939 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
941 error("memory full");
942 table_ident
= ptable
;
945 ts
= malloc(sizeof(TokenSym
) + len
);
947 error("memory full");
949 ts
->tok
= tok_ident
++;
951 ts
->hash_next
= NULL
;
952 memcpy(ts
->str
, str
, len
+ 1);
957 void add_char(char **pp
, int c
)
961 if (c
== '\'' || c
== '\"' || c
== '\\') {
962 /* XXX: could be more precise if char or string */
965 if (c
>= 32 && c
<= 126) {
972 *p
++ = '0' + ((c
>> 6) & 7);
973 *p
++ = '0' + ((c
>> 3) & 7);
974 *p
++ = '0' + (c
& 7);
980 /* XXX: buffer overflow */
981 char *get_tok_str(int v
, CValue
*cv
)
983 static char buf
[STRING_MAX_SIZE
+ 1];
988 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
989 sprintf(buf
, "%u", cv
->ui
);
991 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
998 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
1002 for(i
=0;i
<ts
->len
;i
++)
1003 add_char(&p
, ts
->str
[i
]);
1007 } else if (v
< TOK_IDENT
) {
1012 } else if (v
< tok_ident
) {
1013 return table_ident
[v
- TOK_IDENT
]->str
;
1014 } else if (v
>= SYM_FIRST_ANOM
) {
1015 /* special name for anonymous symbol */
1016 sprintf(buf
, "L.%u", v
- SYM_FIRST_ANOM
);
1019 /* should never happen */
1024 /* push, without hashing */
1025 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1028 s
= malloc(sizeof(Sym
));
1030 error("memory full");
1041 /* find a symbol and return its associated structure. 's' is the top
1042 of the symbol stack */
1043 Sym
*sym_find2(Sym
*s
, int v
)
1053 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1055 /* find a symbol and return its associated structure. 'st' is the
1057 Sym
*sym_find1(SymStack
*st
, int v
)
1061 s
= st
->hash
[HASH_SYM(v
)];
1070 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1073 s
= sym_push2(&st
->top
, v
, t
, c
);
1074 /* add in hash table */
1076 ps
= &st
->hash
[HASH_SYM(v
)];
1083 /* find a symbol in the right symbol space */
1084 Sym
*sym_find(int v
)
1087 s
= sym_find1(&local_stack
, v
);
1089 s
= sym_find1(&global_stack
, v
);
1093 /* push a given symbol on the symbol stack */
1094 Sym
*sym_push(int v
, int t
, int r
, int c
)
1097 if (local_stack
.top
)
1098 s
= sym_push1(&local_stack
, v
, t
, c
);
1100 s
= sym_push1(&global_stack
, v
, t
, c
);
1105 /* pop symbols until top reaches 'b' */
1106 void sym_pop(SymStack
*st
, Sym
*b
)
1113 /* free hash table entry, except if symbol was freed (only
1114 used for #undef symbols) */
1116 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1123 /* undefined a hashed symbol (used for #undef). Its name is set to
1125 void sym_undef(SymStack
*st
, Sym
*s
)
1128 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1129 while (*ss
!= NULL
) {
1132 ss
= &(*ss
)->hash_next
;
1140 BufferedFile
*tcc_open(const char *filename
)
1145 fd
= open(filename
, O_RDONLY
);
1148 bf
= malloc(sizeof(BufferedFile
));
1154 bf
->buf_ptr
= bf
->buffer
;
1155 bf
->buf_end
= bf
->buffer
;
1156 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1157 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1159 // printf("opening '%s'\n", filename);
1163 void tcc_close(BufferedFile
*bf
)
1165 total_lines
+= bf
->line_num
;
1170 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1171 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1173 /* fill input buffer and return next char */
1174 int tcc_getc_slow(BufferedFile
*bf
)
1177 /* only tries to read if really end of buffer */
1178 if (bf
->buf_ptr
>= bf
->buf_end
) {
1180 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1187 bf
->buf_ptr
= bf
->buffer
;
1188 bf
->buf_end
= bf
->buffer
+ len
;
1189 *bf
->buf_end
= CH_EOB
;
1191 if (bf
->buf_ptr
< bf
->buf_end
) {
1192 return *bf
->buf_ptr
++;
1194 bf
->buf_ptr
= bf
->buf_end
;
1199 /* no need to put that inline */
1200 void handle_eob(void)
1203 ch1
= tcc_getc_slow(file
);
1207 if (include_stack_ptr
== include_stack
)
1209 /* add end of include file debug info */
1211 put_stabd(N_EINCL
, 0, 0);
1213 /* pop include stack */
1215 include_stack_ptr
--;
1216 file
= *include_stack_ptr
;
1220 /* read next char from current input file */
1221 static inline void inp(void)
1223 ch1
= TCC_GETC(file
);
1224 /* end of buffer/file handling */
1229 // printf("ch1=%c 0x%x\n", ch1, ch1);
1232 /* input with '\\n' handling */
1233 static inline void minp(void)
1238 if (ch
== '\\' && ch1
== '\n') {
1242 //printf("ch=%c 0x%x\n", ch, ch);
1246 /* same as minp, but also skip comments */
1254 /* single line C++ comments */
1256 while (ch1
!= '\n' && ch1
!= -1)
1259 ch
= ' '; /* return space */
1260 } else if (ch1
== '*') {
1266 if (c
== '*' && ch1
== '/') {
1268 ch
= ' '; /* return space */
1280 void skip_spaces(void)
1282 while (ch
== ' ' || ch
== '\t')
1286 /* skip block of text until #else, #elif or #endif. skip also pairs of
1288 void preprocess_skip(void)
1293 while (ch
!= '\n') {
1304 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1306 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1308 else if (tok
== TOK_ENDIF
)
1314 /* ParseState handling */
1316 /* XXX: currently, no include file info is stored. Thus, we cannot display
1317 accurate messages if the function or data definition spans multiple
1320 /* save current parse state in 's' */
1321 void save_parse_state(ParseState
*s
)
1323 s
->line_num
= file
->line_num
;
1324 s
->macro_ptr
= macro_ptr
;
1329 /* restore parse state from 's' */
1330 void restore_parse_state(ParseState
*s
)
1332 file
->line_num
= s
->line_num
;
1333 macro_ptr
= s
->macro_ptr
;
1338 /* return the number of additionnal 'ints' necessary to store the
1340 static inline int tok_ext_size(int t
)
1358 return LDOUBLE_SIZE
/ 4;
1364 /* token string handling */
1366 static inline void tok_str_new(TokenString
*s
)
1370 s
->last_line_num
= -1;
1373 static void tok_str_add(TokenString
*s
, int t
)
1379 if ((len
& 63) == 0) {
1380 str
= realloc(str
, (len
+ 64) * sizeof(int));
1389 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1393 n
= tok_ext_size(t
);
1395 tok_str_add(s
, cv
->tab
[i
]);
1398 /* add the current parse token in token string 's' */
1399 static void tok_str_add_tok(TokenString
*s
)
1403 /* save line number info */
1404 if (file
->line_num
!= s
->last_line_num
) {
1405 s
->last_line_num
= file
->line_num
;
1406 cval
.i
= s
->last_line_num
;
1407 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1409 tok_str_add2(s
, tok
, &tokc
);
1412 /* get a token from an integer array and increment pointer accordingly */
1413 static int tok_get(int **tok_str
, CValue
*cv
)
1419 n
= tok_ext_size(t
);
1426 /* eval an expression for #if/#elif */
1427 int expr_preprocess(void)
1433 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1434 next(); /* do macro subst */
1435 if (tok
== TOK_DEFINED
) {
1440 c
= sym_find1(&define_stack
, tok
) != 0;
1445 } else if (tok
>= TOK_IDENT
) {
1446 /* if undefined macro */
1450 tok_str_add_tok(&str
);
1452 tok_str_add(&str
, -1); /* simulate end of file */
1453 tok_str_add(&str
, 0);
1454 /* now evaluate C constant expression */
1455 macro_ptr
= str
.str
;
1463 #if defined(DEBUG) || defined(PP_DEBUG)
1464 void tok_print(int *str
)
1470 t
= tok_get(&str
, &cval
);
1473 printf(" %s", get_tok_str(t
, &cval
));
1479 /* parse after #define */
1480 void parse_define(void)
1482 Sym
*s
, *first
, **ps
;
1483 int v
, t
, varg
, is_vaargs
;
1487 /* XXX: should check if same macro (ANSI) */
1490 /* '(' must be just after macro definition for MACRO_FUNC */
1495 while (tok
!= ')') {
1499 if (varg
== TOK_DOTS
) {
1500 varg
= TOK___VA_ARGS__
;
1502 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1506 if (varg
< TOK_IDENT
)
1507 error("badly punctuated parameter list");
1508 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1520 if (ch
== '\n' || ch
== -1)
1523 tok_str_add2(&str
, tok
, &tokc
);
1525 tok_str_add(&str
, 0);
1527 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1530 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1534 void preprocess(void)
1537 char buf
[1024], *q
, *p
;
1542 return_linefeed
= 1; /* linefeed will be returned as a token */
1546 if (tok
== TOK_DEFINE
) {
1549 } else if (tok
== TOK_UNDEF
) {
1551 s
= sym_find1(&define_stack
, tok
);
1552 /* undefine symbol by putting an invalid name */
1554 sym_undef(&define_stack
, s
);
1555 } else if (tok
== TOK_INCLUDE
) {
1560 } else if (ch
== '\"') {
1565 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1566 if ((q
- buf
) < sizeof(buf
) - 1)
1574 error("#include syntax error");
1575 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1578 /* eat all spaces and comments after include */
1579 /* XXX: slightly incorrect */
1580 while (ch1
!= '\n' && ch1
!= -1)
1583 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1584 error("memory full");
1586 /* first search in current dir if "header.h" */
1588 p
= strrchr(file
->filename
, '/');
1590 size
= p
+ 1 - file
->filename
;
1591 if (size
> sizeof(buf1
) - 1)
1592 size
= sizeof(buf1
) - 1;
1593 memcpy(buf1
, file
->filename
, size
);
1595 pstrcat(buf1
, sizeof(buf1
), buf
);
1600 /* now search in standard include path */
1601 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1602 strcpy(buf1
, include_paths
[i
]);
1609 error("include file '%s' not found", buf
);
1612 /* push current file in stack */
1613 /* XXX: fix current line init */
1614 *include_stack_ptr
++ = file
;
1616 /* add include file debug info */
1618 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1622 } else if (tok
== TOK_IFNDEF
) {
1625 } else if (tok
== TOK_IF
) {
1626 c
= expr_preprocess();
1628 } else if (tok
== TOK_IFDEF
) {
1632 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1634 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1635 error("memory full");
1636 *ifdef_stack_ptr
++ = c
;
1638 } else if (tok
== TOK_ELSE
) {
1639 if (ifdef_stack_ptr
== ifdef_stack
)
1640 error("#else without matching #if");
1641 if (ifdef_stack_ptr
[-1] & 2)
1642 error("#else after #else");
1643 c
= (ifdef_stack_ptr
[-1] ^= 3);
1645 } else if (tok
== TOK_ELIF
) {
1646 if (ifdef_stack_ptr
== ifdef_stack
)
1647 error("#elif without matching #if");
1648 c
= ifdef_stack_ptr
[-1];
1650 error("#elif after #else");
1651 /* last #if/#elif expression was true: we skip */
1654 c
= expr_preprocess();
1655 ifdef_stack_ptr
[-1] = c
;
1662 } else if (tok
== TOK_ENDIF
) {
1663 if (ifdef_stack_ptr
== ifdef_stack
)
1664 error("#endif without matching #if");
1666 } else if (tok
== TOK_LINE
) {
1668 if (tok
!= TOK_CINT
)
1670 file
->line_num
= tokc
.i
;
1676 pstrcpy(file
->filename
, sizeof(file
->filename
),
1677 get_tok_str(tok
, &tokc
));
1679 } else if (tok
== TOK_ERROR
) {
1682 /* ignore other preprocess commands or #! for C scripts */
1683 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
1686 return_linefeed
= 0;
1689 /* read a number in base b */
1690 static int getn(int b
)
1695 if (ch
>= 'a' && ch
<= 'f')
1697 else if (ch
>= 'A' && ch
<= 'F')
1703 if (t
< 0 || t
>= b
)
1711 /* read a character for string or char constant and eval escape codes */
1712 static int getq(void)
1720 /* at most three octal digits */
1724 c
= c
* 8 + ch
- '0';
1727 c
= c
* 8 + ch
- '0';
1732 } else if (ch
== 'x') {
1750 else if (ch
== 'e' && gnu_ext
)
1752 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1755 error("invalid escaped char");
1762 /* we use 64 bit numbers */
1765 /* bn = (bn << shift) | or_val */
1766 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1770 for(i
=0;i
<BN_SIZE
;i
++) {
1772 bn
[i
] = (v
<< shift
) | or_val
;
1773 or_val
= v
>> (32 - shift
);
1777 void bn_zero(unsigned int *bn
)
1780 for(i
=0;i
<BN_SIZE
;i
++) {
1785 void parse_number(void)
1787 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1789 unsigned int bn
[BN_SIZE
];
1799 /* special dot handling */
1800 if (ch
>= '0' && ch
<= '9') {
1801 goto float_frac_parse
;
1802 } else if (ch
== '.') {
1813 } else if (t
== '0') {
1814 if (ch
== 'x' || ch
== 'X') {
1818 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1824 /* parse all digits. cannot check octal numbers at this stage
1825 because of floating point constants */
1827 if (ch
>= 'a' && ch
<= 'f')
1829 else if (ch
>= 'A' && ch
<= 'F')
1837 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1839 error("number too long");
1845 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1846 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1848 /* NOTE: strtox should support that for hexa numbers, but
1849 non ISOC99 libcs do not support it, so we prefer to do
1851 /* hexadecimal or binary floats */
1852 /* XXX: handle overflows */
1864 } else if (t
>= 'a') {
1866 } else if (t
>= 'A') {
1871 bn_lshift(bn
, shift
, t
);
1878 if (t
>= 'a' && t
<= 'f') {
1880 } else if (t
>= 'A' && t
<= 'F') {
1882 } else if (t
>= '0' && t
<= '9') {
1888 error("invalid digit");
1889 bn_lshift(bn
, shift
, t
);
1894 if (ch
!= 'p' && ch
!= 'P')
1895 error("exponent expected");
1901 } else if (ch
== '-') {
1905 if (ch
< '0' || ch
> '9')
1906 error("exponent digits expected");
1907 while (ch
>= '0' && ch
<= '9') {
1908 exp_val
= exp_val
* 10 + ch
- '0';
1911 exp_val
= exp_val
* s
;
1913 /* now we can generate the number */
1914 /* XXX: should patch directly float number */
1915 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1916 d
= ldexp(d
, exp_val
- frac_bits
);
1921 /* float : should handle overflow */
1923 } else if (t
== 'L') {
1926 /* XXX: not large enough */
1927 tokc
.ld
= (long double)d
;
1933 /* decimal floats */
1935 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1940 while (ch
>= '0' && ch
<= '9') {
1941 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1947 if (ch
== 'e' || ch
== 'E') {
1948 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1952 if (ch
== '-' || ch
== '+') {
1953 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1958 if (ch
< '0' || ch
> '9')
1959 error("exponent digits expected");
1960 while (ch
>= '0' && ch
<= '9') {
1961 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1973 tokc
.f
= strtof(token_buf
, NULL
);
1974 } else if (t
== 'L') {
1977 tokc
.ld
= strtold(token_buf
, NULL
);
1980 tokc
.d
= strtod(token_buf
, NULL
);
1984 unsigned long long n
, n1
;
1987 /* integer number */
1990 if (b
== 10 && *q
== '0') {
1997 /* no need for checks except for base 10 / 8 errors */
2000 } else if (t
>= 'a') {
2002 } else if (t
>= 'A') {
2007 error("invalid digit");
2011 /* detect overflow */
2013 error("integer constant overflow");
2016 /* XXX: not exactly ANSI compliant */
2017 if ((n
& 0xffffffff00000000LL
) != 0) {
2022 } else if (n
> 0x7fffffff) {
2032 error("three 'l' in integer constant");
2035 if (tok
== TOK_CINT
)
2037 else if (tok
== TOK_CUINT
)
2041 } else if (t
== 'U') {
2042 if (tok
== TOK_CINT
)
2044 else if (tok
== TOK_CLLONG
)
2051 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2059 /* return next token without macro substitution */
2060 void next_nomacro1(void)
2068 while (ch
== '\n') {
2069 /* during preprocessor parsing, '\n' is a token */
2070 if (return_linefeed
) {
2075 while (ch
== ' ' || ch
== '\t')
2078 /* preprocessor command if # at start of line after
2083 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2101 while (isid(ch
) || isnum(ch
)) {
2102 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2103 error("ident too long");
2108 ts
= tok_alloc(token_buf
, q
- token_buf
);
2110 } else if (isnum(ch
) || ch
== '.') {
2112 } else if (ch
== '\'') {
2117 /* this cast is needed if >= 128 */
2118 if (tok
== TOK_CCHAR
)
2124 } else if (ch
== '\"') {
2129 while (ch
!= '\"') {
2132 error("unterminated string");
2133 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2134 error("string too long");
2138 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2141 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2146 if (*q
== tok
&& q
[1] == ch
) {
2149 /* three chars tests */
2150 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2155 } else if (tok
== TOK_DOTS
) {
2157 error("parse error");
2164 /* single char substitutions */
2167 else if (tok
== '>')
2172 /* return next token without macro substitution. Can read input from
2180 tok
= tok_get(¯o_ptr
, &tokc
);
2181 if (tok
== TOK_LINENUM
) {
2182 file
->line_num
= tokc
.i
;
2191 /* substitute args in macro_str and return allocated string */
2192 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2194 int *st
, last_tok
, t
, notfirst
;
2203 t
= tok_get(¯o_str
, &cval
);
2208 t
= tok_get(¯o_str
, &cval
);
2211 s
= sym_find2(args
, t
);
2213 token_buf
[0] = '\0';
2218 pstrcat(token_buf
, sizeof(token_buf
), " ");
2219 t
= tok_get(&st
, &cval
);
2220 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2224 printf("stringize: %s\n", token_buf
);
2227 ts
= tok_alloc(token_buf
, 0);
2229 tok_str_add2(&str
, TOK_STR
, &cval
);
2231 tok_str_add2(&str
, t
, &cval
);
2233 } else if (t
>= TOK_IDENT
) {
2234 s
= sym_find2(args
, t
);
2237 /* if '##' is present before or after, no arg substitution */
2238 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2239 /* special case for var arg macros : ## eats the
2240 ',' if empty VA_ARGS riable. */
2241 /* XXX: test of the ',' is not 100%
2242 reliable. should fix it to avoid security
2244 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2245 last_tok
== TOK_TWOSHARPS
&&
2246 str
.len
>= 2&& str
.str
[str
.len
- 2] == ',') {
2247 /* suppress ',' '##' */
2251 tok_str_add(&str
, *st
++);
2254 macro_subst(&str
, nested_list
, st
);
2257 tok_str_add(&str
, t
);
2260 tok_str_add2(&str
, t
, &cval
);
2264 tok_str_add(&str
, 0);
2268 /* handle the '##' operator */
2269 int *macro_twosharps(int *macro_str
)
2276 TokenString macro_str1
;
2278 tok_str_new(¯o_str1
);
2284 while (*macro_ptr
== TOK_TWOSHARPS
) {
2286 macro_ptr1
= macro_ptr
;
2289 t
= tok_get(¯o_ptr
, &cval
);
2290 /* XXX: we handle only most common cases:
2291 ident + ident or ident + number */
2292 if (tok
>= TOK_IDENT
&&
2293 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2294 p
= get_tok_str(tok
, &tokc
);
2295 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2296 p
= get_tok_str(t
, &cval
);
2297 pstrcat(token_buf
, sizeof(token_buf
), p
);
2298 ts
= tok_alloc(token_buf
, 0);
2299 tok
= ts
->tok
; /* modify current token */
2301 /* cannot merge tokens: skip '##' */
2302 macro_ptr
= macro_ptr1
;
2307 tok_str_add2(¯o_str1
, tok
, &tokc
);
2309 tok_str_add(¯o_str1
, 0);
2310 return macro_str1
.str
;
2313 /* do macro substitution of macro_str and add result to
2314 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2315 substituted. 'nested_list' is the list of all macros we got inside
2316 to avoid recursing. */
2317 void macro_subst(TokenString
*tok_str
,
2318 Sym
**nested_list
, int *macro_str
)
2320 Sym
*s
, *args
, *sa
, *sa1
;
2321 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2322 int mstr_allocated
, *macro_str1
;
2326 saved_macro_ptr
= macro_ptr
;
2327 macro_ptr
= macro_str
;
2330 /* first scan for '##' operator handling */
2331 macro_str1
= macro_twosharps(macro_str
);
2332 macro_ptr
= macro_str1
;
2339 /* special macros */
2340 if (tok
== TOK___LINE__
) {
2341 cval
.i
= file
->line_num
;
2342 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2343 } else if (tok
== TOK___FILE__
) {
2344 cval
.ts
= tok_alloc(file
->filename
, 0);
2345 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2346 } else if (tok
== TOK___DATE__
) {
2347 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2348 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2349 } else if (tok
== TOK___TIME__
) {
2350 cval
.ts
= tok_alloc("00:00:00", 0);
2351 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2352 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2353 /* if symbol is a macro, prepare substitution */
2354 /* if nested substitution, do nothing */
2355 if (sym_find2(*nested_list
, tok
))
2359 if (s
->t
== MACRO_FUNC
) {
2360 /* NOTE: we do not use next_nomacro to avoid eating the
2361 next token. XXX: find better solution */
2365 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2369 if (t
!= '(') /* no macro subst */
2372 /* argument macro */
2377 /* NOTE: empty args are allowed, except if no args */
2379 /* handle '()' case */
2380 if (!args
&& tok
== ')')
2383 error("macro '%s' used with too many args",
2384 get_tok_str(s
->v
, 0));
2387 /* NOTE: non zero sa->t indicates VA_ARGS */
2388 while ((parlevel
> 0 ||
2390 (tok
!= ',' || sa
->t
))) &&
2394 else if (tok
== ')')
2396 tok_str_add2(&str
, tok
, &tokc
);
2399 tok_str_add(&str
, 0);
2400 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2403 /* special case for gcc var args: add an empty
2404 var arg argument if it is omitted */
2405 if (sa
&& sa
->t
&& gnu_ext
)
2415 error("macro '%s' used with too few args",
2416 get_tok_str(s
->v
, 0));
2419 /* now subst each arg */
2420 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2431 sym_push2(nested_list
, s
->v
, 0, 0);
2432 macro_subst(tok_str
, nested_list
, mstr
);
2433 /* pop nested defined symbol */
2435 *nested_list
= sa1
->prev
;
2441 /* no need to add if reading input stream */
2444 tok_str_add2(tok_str
, tok
, &tokc
);
2446 /* only replace one macro while parsing input stream */
2450 macro_ptr
= saved_macro_ptr
;
2455 /* return next token with macro substitution */
2461 /* special 'ungettok' case for label parsing */
2469 /* if not reading from macro substituted string, then try
2471 /* XXX: optimize non macro case */
2474 macro_subst(&str
, &nested_list
, NULL
);
2476 tok_str_add(&str
, 0);
2477 macro_ptr
= str
.str
;
2478 macro_ptr_allocated
= str
.str
;
2486 /* end of macro string: free it */
2487 free(macro_ptr_allocated
);
2494 printf("token = %s\n", get_tok_str(tok
, &tokc
));
2498 void swap(int *p
, int *q
)
2506 void vsetc(int t
, int r
, CValue
*vc
)
2508 if (vtop
>= vstack
+ VSTACK_SIZE
)
2509 error("memory full");
2510 /* cannot let cpu flags if other instruction are generated */
2511 /* XXX: VT_JMP test too ? */
2512 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2517 vtop
->r2
= VT_CONST
;
2521 /* push integer constant */
2526 vsetc(VT_INT
, VT_CONST
, &cval
);
2529 /* Return a static symbol pointing to a section */
2530 static Sym
*get_sym_ref(int t
, Section
*sec
,
2531 unsigned long offset
, unsigned long size
)
2537 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2538 sym
->r
= VT_CONST
| VT_SYM
;
2539 put_extern_sym(sym
, sec
, offset
);
2543 /* push a reference to a section offset by adding a dummy symbol */
2545 void vpush_ref(int t
, Section
*sec
, unsigned long offset
)
2549 cval
.sym
= get_sym_ref(t
, sec
, offset
, 0);
2550 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2553 /* push a reference to symbol v */
2554 void vpush_sym(int t
, int v
)
2559 sym
= external_sym(v
, t
, 0);
2561 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2564 void vset(int t
, int r
, int v
)
2581 void vpushv(SValue
*v
)
2583 if (vtop
>= vstack
+ VSTACK_SIZE
)
2584 error("memory full");
2594 /* save r to the memory stack, and mark it as being free */
2595 void save_reg(int r
)
2597 int l
, i
, saved
, t
, size
, align
;
2600 /* modify all stack values */
2603 for(p
=vstack
;p
<=vtop
;p
++) {
2604 i
= p
->r
& VT_VALMASK
;
2605 if ((p
->r
& VT_VALMASK
) == r
||
2606 (p
->r2
& VT_VALMASK
) == r
) {
2607 /* must save value on stack if not already done */
2609 /* store register in the stack */
2611 if ((p
->r
& VT_LVAL
) ||
2612 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2614 size
= type_size(t
, &align
);
2615 loc
= (loc
- size
) & -align
;
2617 sv
.r
= VT_LOCAL
| VT_LVAL
;
2620 #ifdef TCC_TARGET_I386
2621 /* x86 specific: need to pop fp register ST0 if saved */
2623 o(0xd9dd); /* fstp %st(1) */
2626 /* special long long case */
2627 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2634 /* mark that stack entry as being saved on the stack */
2646 /* find a free register of class 'rc'. If none, save one register */
2652 /* find a free register */
2653 for(r
=0;r
<NB_REGS
;r
++) {
2654 if (reg_classes
[r
] & rc
) {
2655 for(p
=vstack
;p
<=vtop
;p
++) {
2656 if ((p
->r
& VT_VALMASK
) == r
||
2657 (p
->r2
& VT_VALMASK
) == r
)
2665 /* no register left : free the first one on the stack (VERY
2666 IMPORTANT to start from the bottom to ensure that we don't
2667 spill registers used in gen_opi()) */
2668 for(p
=vstack
;p
<=vtop
;p
++) {
2669 r
= p
->r
& VT_VALMASK
;
2670 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2678 /* save registers up to (vtop - n) stack entry */
2679 void save_regs(int n
)
2684 for(p
= vstack
;p
<= p1
; p
++) {
2685 r
= p
->r
& VT_VALMASK
;
2692 /* move register 's' to 'r', and flush previous value of r to memory
2694 void move_reg(int r
, int s
)
2707 /* get address of vtop (vtop MUST BE an lvalue) */
2710 vtop
->r
&= ~VT_LVAL
;
2711 /* tricky: if saved lvalue, then we can go back to lvalue */
2712 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2713 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2716 #ifdef CONFIG_TCC_BCHECK
2717 /* generate lvalue bound code */
2722 vtop
->r
&= ~VT_MUSTBOUND
;
2723 /* if lvalue, then use checking code before dereferencing */
2724 if (vtop
->r
& VT_LVAL
) {
2725 /* if not VT_BOUNDED value, then make one */
2726 if (!(vtop
->r
& VT_BOUNDED
)) {
2727 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2730 gen_bounded_ptr_add();
2731 vtop
->r
|= lval_type
;
2733 /* then check for dereferencing */
2734 gen_bounded_ptr_deref();
2739 /* store vtop a register belonging to class 'rc'. lvalues are
2740 converted to values. Cannot be used if cannot be converted to
2741 register value (such as structures). */
2744 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
2745 unsigned long long ll
;
2747 /* NOTE: get_reg can modify vstack[] */
2748 if (vtop
->t
& VT_BITFIELD
) {
2749 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2750 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2751 /* remove bit field info to avoid loops */
2752 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2753 /* generate shifts */
2754 vpushi(32 - (bit_pos
+ bit_size
));
2756 vpushi(32 - bit_size
);
2757 /* NOTE: transformed to SHR if unsigned */
2761 if (is_float(vtop
->t
) &&
2762 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2767 /* XXX: unify with initializers handling ? */
2768 /* CPUs usually cannot use float constants, so we store them
2769 generically in data segment */
2770 size
= type_size(vtop
->t
, &align
);
2771 data_section
->data_offset
= (data_section
->data_offset
+
2772 align
- 1) & -align
;
2773 /* XXX: not portable yet */
2774 ptr
= section_ptr(data_section
, size
);
2777 ptr
[i
] = vtop
->c
.tab
[i
];
2780 sym
= sym_push1(&global_stack
, v
, vtop
->t
| VT_STATIC
, 0);
2781 sym
->r
= VT_CONST
| VT_SYM
;
2782 put_extern_sym(sym
, data_section
, data_section
->data_offset
);
2784 vtop
->r
|= VT_LVAL
| VT_SYM
;
2786 data_section
->data_offset
+= size
<< 2;
2788 #ifdef CONFIG_TCC_BCHECK
2789 if (vtop
->r
& VT_MUSTBOUND
)
2793 r
= vtop
->r
& VT_VALMASK
;
2794 /* need to reload if:
2796 - lvalue (need to dereference pointer)
2797 - already a register, but not in the right class */
2798 if (r
>= VT_CONST
||
2799 (vtop
->r
& VT_LVAL
) ||
2800 !(reg_classes
[r
] & rc
) ||
2801 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2802 !(reg_classes
[vtop
->r2
] & rc
))) {
2804 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2805 /* two register type load : expand to two words
2807 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2810 vtop
->c
.ui
= ll
; /* first word */
2812 vtop
->r
= r
; /* save register value */
2813 vpushi(ll
>> 32); /* second word */
2814 } else if (r
>= VT_CONST
||
2815 (vtop
->r
& VT_LVAL
)) {
2816 /* load from memory */
2819 vtop
[-1].r
= r
; /* save register value */
2820 /* increment pointer to get second word */
2827 /* move registers */
2830 vtop
[-1].r
= r
; /* save register value */
2831 vtop
->r
= vtop
[-1].r2
;
2833 /* allocate second register */
2840 /* write second register */
2842 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2844 /* lvalue of scalar type : need to use lvalue type
2845 because of possible cast */
2848 /* compute memory access type */
2849 if (vtop
->r
& VT_LVAL_BYTE
)
2851 else if (vtop
->r
& VT_LVAL_SHORT
)
2853 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2857 /* restore wanted type */
2860 /* one register type load */
2869 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2870 void gv2(int rc1
, int rc2
)
2872 /* generate more generic register first */
2878 /* test if reload is needed for first register */
2879 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2889 /* test if reload is needed for first register */
2890 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2896 /* expand long long on stack in two int registers */
2901 u
= vtop
->t
& VT_UNSIGNED
;
2904 vtop
[0].r
= vtop
[-1].r2
;
2905 vtop
[0].r2
= VT_CONST
;
2906 vtop
[-1].r2
= VT_CONST
;
2907 vtop
[0].t
= VT_INT
| u
;
2908 vtop
[-1].t
= VT_INT
| u
;
2911 /* build a long long from two ints */
2914 gv2(RC_INT
, RC_INT
);
2915 vtop
[-1].r2
= vtop
[0].r
;
2920 /* rotate n first stack elements to the bottom */
2927 for(i
=-n
+1;i
!=0;i
++)
2928 vtop
[i
] = vtop
[i
+1];
2932 /* pop stack value */
2936 v
= vtop
->r
& VT_VALMASK
;
2937 #ifdef TCC_TARGET_I386
2938 /* for x86, we need to pop the FP stack */
2940 o(0xd9dd); /* fstp %st(1) */
2943 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2944 /* need to put correct jump if && or || without test */
2950 /* convert stack entry to register and duplicate its value in another
2958 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2965 /* stack: H L L1 H1 */
2973 /* duplicate value */
2984 load(r1
, &sv
); /* move r to r1 */
2986 /* duplicates value */
2991 /* generate CPU independent (unsigned) long long operations */
2992 void gen_opl(int op
)
2994 int t
, a
, b
, op1
, c
, i
;
3002 func
= TOK___divdi3
;
3005 func
= TOK___udivdi3
;
3008 func
= TOK___moddi3
;
3011 func
= TOK___umoddi3
;
3013 /* call generic long long function */
3014 gfunc_start(&gf
, FUNC_CDECL
);
3017 vpush_sym(func_old_type
, func
);
3021 vtop
->r2
= REG_LRET
;
3034 /* stack: L1 H1 L2 H2 */
3039 vtop
[-2] = vtop
[-3];
3042 /* stack: H1 H2 L1 L2 */
3048 /* stack: H1 H2 L1 L2 ML MH */
3051 /* stack: ML MH H1 H2 L1 L2 */
3055 /* stack: ML MH H1 L2 H2 L1 */
3060 /* stack: ML MH M1 M2 */
3063 } else if (op
== '+' || op
== '-') {
3064 /* XXX: add non carry method too (for MIPS or alpha) */
3070 /* stack: H1 H2 (L1 op L2) */
3073 gen_op(op1
+ 1); /* TOK_xxxC2 */
3076 /* stack: H1 H2 (L1 op L2) */
3079 /* stack: (L1 op L2) H1 H2 */
3081 /* stack: (L1 op L2) (H1 op H2) */
3089 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3094 /* stack: L H shift */
3096 /* constant: simpler */
3097 /* NOTE: all comments are for SHL. the other cases are
3098 done by swaping words */
3109 if (op
!= TOK_SAR
) {
3139 /* XXX: should provide a faster fallback on x86 ? */
3142 func
= TOK___sardi3
;
3145 func
= TOK___shrdi3
;
3148 func
= TOK___shldi3
;
3154 /* compare operations */
3160 /* stack: L1 H1 L2 H2 */
3162 vtop
[-1] = vtop
[-2];
3164 /* stack: L1 L2 H1 H2 */
3167 /* when values are equal, we need to compare low words. since
3168 the jump is inverted, we invert the test too. */
3171 else if (op1
== TOK_GT
)
3173 else if (op1
== TOK_ULT
)
3175 else if (op1
== TOK_UGT
)
3180 if (op1
!= TOK_NE
) {
3184 /* generate non equal test */
3185 /* XXX: NOT PORTABLE yet */
3189 #ifdef TCC_TARGET_I386
3190 b
= psym(0x850f, 0);
3192 error("not implemented");
3200 vset(VT_INT
, VT_JMPI
, a
);
3205 /* handle integer constant optimizations and various machine
3207 void gen_opic(int op
)
3214 /* currently, we cannot do computations with forward symbols */
3215 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3216 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3220 case '+': v1
->c
.i
+= fc
; break;
3221 case '-': v1
->c
.i
-= fc
; break;
3222 case '&': v1
->c
.i
&= fc
; break;
3223 case '^': v1
->c
.i
^= fc
; break;
3224 case '|': v1
->c
.i
|= fc
; break;
3225 case '*': v1
->c
.i
*= fc
; break;
3232 /* if division by zero, generate explicit division */
3235 error("division by zero in constant");
3239 default: v1
->c
.i
/= fc
; break;
3240 case '%': v1
->c
.i
%= fc
; break;
3241 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3242 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3245 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3246 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3247 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3249 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3250 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3251 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3252 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3253 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3254 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3255 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3256 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3257 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3258 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3260 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3261 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3267 /* if commutative ops, put c2 as constant */
3268 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3269 op
== '|' || op
== '*')) {
3274 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3277 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3278 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3284 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3285 /* try to use shifts instead of muls or divs */
3286 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3295 else if (op
== TOK_PDIV
)
3303 /* call low level op generator */
3309 /* generate a floating point operation with constant propagation */
3310 void gen_opif(int op
)
3318 /* currently, we cannot do computations with forward symbols */
3319 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3320 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3322 if (v1
->t
== VT_FLOAT
) {
3325 } else if (v1
->t
== VT_DOUBLE
) {
3333 /* NOTE: we only do constant propagation if finite number (not
3334 NaN or infinity) (ANSI spec) */
3335 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3339 case '+': f1
+= f2
; break;
3340 case '-': f1
-= f2
; break;
3341 case '*': f1
*= f2
; break;
3345 error("division by zero in constant");
3350 /* XXX: also handles tests ? */
3354 /* XXX: overflow test ? */
3355 if (v1
->t
== VT_FLOAT
) {
3357 } else if (v1
->t
== VT_DOUBLE
) {
3370 int pointed_size(int t
)
3372 return type_size(pointed_type(t
), &t
);
3376 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3378 char buf1
[256], buf2
[256];
3382 if (!is_compatible_types(t1
, t2
)) {
3383 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3384 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3385 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3390 /* generic gen_op: handles types problems */
3393 int u
, t1
, t2
, bt1
, bt2
, t
;
3397 bt1
= t1
& VT_BTYPE
;
3398 bt2
= t2
& VT_BTYPE
;
3400 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3401 /* at least one operand is a pointer */
3402 /* relationnal op: must be both pointers */
3403 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3404 // check_pointer_types(vtop, vtop - 1);
3405 /* pointers are handled are unsigned */
3406 t
= VT_INT
| VT_UNSIGNED
;
3409 /* if both pointers, then it must be the '-' op */
3410 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3411 (t2
& VT_BTYPE
) == VT_PTR
) {
3413 error("cannot use pointers here");
3414 // check_pointer_types(vtop - 1, vtop);
3415 /* XXX: check that types are compatible */
3416 u
= pointed_size(t1
);
3418 /* set to integer type */
3423 /* exactly one pointer : must be '+' or '-'. */
3424 if (op
!= '-' && op
!= '+')
3425 error("cannot use pointers here");
3426 /* Put pointer as first operand */
3427 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3431 /* XXX: cast to int ? (long long case) */
3432 vpushi(pointed_size(vtop
[-1].t
));
3434 #ifdef CONFIG_TCC_BCHECK
3435 /* if evaluating constant expression, no code should be
3436 generated, so no bound check */
3437 if (do_bounds_check
&& !const_wanted
) {
3438 /* if bounded pointers, we generate a special code to
3445 gen_bounded_ptr_add();
3451 /* put again type if gen_opic() swaped operands */
3454 } else if (is_float(bt1
) || is_float(bt2
)) {
3455 /* compute bigger type and do implicit casts */
3456 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3458 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3463 /* floats can only be used for a few operations */
3464 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3465 (op
< TOK_ULT
|| op
> TOK_GT
))
3466 error("invalid operands for binary operation");
3468 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3469 /* cast to biggest op */
3471 /* convert to unsigned if it does not fit in a long long */
3472 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3473 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3477 /* integer operations */
3479 /* convert to unsigned if it does not fit in an integer */
3480 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3481 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3484 /* XXX: currently, some unsigned operations are explicit, so
3485 we modify them here */
3486 if (t
& VT_UNSIGNED
) {
3493 else if (op
== TOK_LT
)
3495 else if (op
== TOK_GT
)
3497 else if (op
== TOK_LE
)
3499 else if (op
== TOK_GE
)
3505 /* special case for shifts and long long: we keep the shift as
3507 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3513 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3517 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3518 /* relationnal op: the result is an int */
3526 /* generic itof for unsigned long long case */
3527 void gen_cvt_itof1(int t
)
3531 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3532 (VT_LLONG
| VT_UNSIGNED
)) {
3534 gfunc_start(&gf
, FUNC_CDECL
);
3537 vpush_sym(func_old_type
, TOK___ulltof
);
3538 else if (t
== VT_DOUBLE
)
3539 vpush_sym(func_old_type
, TOK___ulltod
);
3541 vpush_sym(func_old_type
, TOK___ulltold
);
3550 /* generic ftoi for unsigned long long case */
3551 void gen_cvt_ftoi1(int t
)
3556 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3557 /* not handled natively */
3558 gfunc_start(&gf
, FUNC_CDECL
);
3559 st
= vtop
->t
& VT_BTYPE
;
3562 vpush_sym(func_old_type
, TOK___fixunssfdi
);
3563 else if (st
== VT_DOUBLE
)
3564 vpush_sym(func_old_type
, TOK___fixunsdfdi
);
3566 vpush_sym(func_old_type
, TOK___fixunsxfdi
);
3570 vtop
->r2
= REG_LRET
;
3576 /* force char or short cast */
3577 void force_charshort_cast(int t
)
3581 /* XXX: add optimization if lvalue : just change type and offset */
3586 if (t
& VT_UNSIGNED
) {
3587 vpushi((1 << bits
) - 1);
3598 /* cast 'vtop' to 't' type */
3599 void gen_cast(int t
)
3601 int sbt
, dbt
, sf
, df
, c
;
3603 /* special delayed cast for char/short */
3604 /* XXX: in some cases (multiple cascaded casts), it may still
3606 if (vtop
->r
& VT_MUSTCAST
) {
3607 vtop
->r
&= ~VT_MUSTCAST
;
3608 force_charshort_cast(vtop
->t
);
3611 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3612 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3617 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3619 /* convert from fp to fp */
3621 /* constant case: we can do it now */
3622 /* XXX: in ISOC, cannot do it if error in convert */
3623 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3624 vtop
->c
.f
= (float)vtop
->c
.d
;
3625 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3626 vtop
->c
.f
= (float)vtop
->c
.ld
;
3627 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3628 vtop
->c
.d
= (double)vtop
->c
.f
;
3629 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3630 vtop
->c
.d
= (double)vtop
->c
.ld
;
3631 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3632 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3633 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3634 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3636 /* non constant case: generate code */
3640 /* convert int to fp */
3643 case VT_LLONG
| VT_UNSIGNED
:
3645 /* XXX: add const cases for long long */
3647 case VT_INT
| VT_UNSIGNED
:
3649 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3650 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3651 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3656 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3657 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3658 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3667 /* convert fp to int */
3668 /* we handle char/short/etc... with generic code */
3669 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3670 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3675 case VT_LLONG
| VT_UNSIGNED
:
3677 /* XXX: add const cases for long long */
3679 case VT_INT
| VT_UNSIGNED
:
3681 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3682 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3683 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3689 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3690 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3691 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3699 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3700 /* additionnal cast for char/short/bool... */
3704 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3705 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3706 /* scalar to long long */
3708 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3709 vtop
->c
.ll
= vtop
->c
.ui
;
3711 vtop
->c
.ll
= vtop
->c
.i
;
3713 /* machine independant conversion */
3715 /* generate high word */
3716 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3724 /* patch second register */
3725 vtop
[-1].r2
= vtop
->r
;
3729 } else if (dbt
== VT_BOOL
) {
3730 /* scalar to bool */
3733 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3734 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3735 force_charshort_cast(t
);
3736 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3738 if (sbt
== VT_LLONG
) {
3739 /* from long long: just take low order word */
3743 /* if lvalue and single word type, nothing to do because
3744 the lvalue already contains the real type size (see
3745 VT_LVAL_xxx constants) */
3751 /* return type size. Put alignment at 'a' */
3752 int type_size(int t
, int *a
)
3758 if (bt
== VT_STRUCT
) {
3760 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3761 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3763 } else if (bt
== VT_PTR
) {
3765 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3766 return type_size(s
->t
, a
) * s
->c
;
3771 } else if (bt
== VT_LDOUBLE
) {
3773 return LDOUBLE_SIZE
;
3774 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3777 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3780 } else if (bt
== VT_SHORT
) {
3784 /* char, void, function, _Bool */
3790 /* return the pointed type of t */
3791 int pointed_type(int t
)
3794 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3795 return s
->t
| (t
& ~VT_TYPE
);
3798 int mk_pointer(int t
)
3802 sym_push(p
, t
, 0, -1);
3803 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3806 int is_compatible_types(int t1
, int t2
)
3813 bt1
= t1
& VT_BTYPE
;
3814 bt2
= t2
& VT_BTYPE
;
3815 if (bt1
== VT_PTR
) {
3816 t1
= pointed_type(t1
);
3817 /* if function, then convert implicitely to function pointer */
3818 if (bt2
!= VT_FUNC
) {
3821 t2
= pointed_type(t2
);
3823 /* void matches everything */
3826 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3828 return is_compatible_types(t1
, t2
);
3829 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3831 } else if (bt1
== VT_FUNC
) {
3834 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3835 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3836 if (!is_compatible_types(s1
->t
, s2
->t
))
3838 /* XXX: not complete */
3839 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3843 while (s1
!= NULL
) {
3846 if (!is_compatible_types(s1
->t
, s2
->t
))
3855 /* XXX: not complete */
3860 /* print a type. If 'varstr' is not NULL, then the variable is also
3861 printed in the type */
3863 /* XXX: add array and function pointers */
3864 void type_to_str(char *buf
, int buf_size
,
3865 int t
, const char *varstr
)
3875 if (t
& VT_UNSIGNED
)
3876 pstrcat(buf
, buf_size
, "unsigned ");
3906 tstr
= "long double";
3908 pstrcat(buf
, buf_size
, tstr
);
3912 if (bt
== VT_STRUCT
)
3916 pstrcat(buf
, buf_size
, tstr
);
3917 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3918 if (v
>= SYM_FIRST_ANOM
)
3919 pstrcat(buf
, buf_size
, "<anonymous>");
3921 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3924 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3925 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3926 pstrcat(buf
, buf_size
, "(");
3928 while (sa
!= NULL
) {
3929 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3930 pstrcat(buf
, buf_size
, buf1
);
3933 pstrcat(buf
, buf_size
, ", ");
3935 pstrcat(buf
, buf_size
, ")");
3938 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3939 pstrcpy(buf1
, sizeof(buf1
), "*");
3941 pstrcat(buf1
, sizeof(buf1
), varstr
);
3942 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3946 pstrcat(buf
, buf_size
, " ");
3947 pstrcat(buf
, buf_size
, varstr
);
3952 /* verify type compatibility to store vtop in 'dt' type, and generate
3954 void gen_assign_cast(int dt
)
3957 char buf1
[256], buf2
[256];
3959 st
= vtop
->t
; /* source type */
3960 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3961 /* special cases for pointers */
3962 /* a function is implicitely a function pointer */
3963 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3964 if (!is_compatible_types(pointed_type(dt
), st
))
3969 /* '0' can also be a pointer */
3970 if ((st
& VT_BTYPE
) == VT_INT
&&
3971 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3975 if (!is_compatible_types(dt
, st
)) {
3977 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3978 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3979 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3985 /* store vtop in lvalue pushed on stack */
3988 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3992 sbt
= vtop
->t
& VT_BTYPE
;
3993 dbt
= ft
& VT_BTYPE
;
3994 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3995 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3996 /* optimize char/short casts */
3997 delayed_cast
= VT_MUSTCAST
;
3998 vtop
->t
= ft
& VT_TYPE
;
4001 gen_assign_cast(ft
& VT_TYPE
);
4004 if (sbt
== VT_STRUCT
) {
4005 /* if structure, only generate pointer */
4006 /* structure assignment : generate memcpy */
4007 /* XXX: optimize if small size */
4009 gfunc_start(&gf
, FUNC_CDECL
);
4011 size
= type_size(vtop
->t
, &align
);
4025 vpush_sym(func_old_type
, TOK_memcpy
);
4027 /* leave source on stack */
4028 } else if (ft
& VT_BITFIELD
) {
4029 /* bitfield store handling */
4030 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4031 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4032 /* remove bit field info to avoid loops */
4033 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4035 /* duplicate destination */
4037 vtop
[-1] = vtop
[-2];
4039 /* mask and shift source */
4040 vpushi((1 << bit_size
) - 1);
4044 /* load destination, mask and or with source */
4046 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4052 #ifdef CONFIG_TCC_BCHECK
4053 /* bound check case */
4054 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4063 r
= gv(rc
); /* generate value */
4064 /* if lvalue was saved on stack, must read it */
4065 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4067 t
= get_reg(RC_INT
);
4069 sv
.r
= VT_LOCAL
| VT_LVAL
;
4070 sv
.c
.ul
= vtop
[-1].c
.ul
;
4072 vtop
[-1].r
= t
| VT_LVAL
;
4075 /* two word case handling : store second register at word + 4 */
4076 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4078 /* convert to int to increment easily */
4085 /* XXX: it works because r2 is spilled last ! */
4086 store(vtop
->r2
, vtop
- 1);
4089 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4090 vtop
->r
|= delayed_cast
;
4094 /* post defines POST/PRE add. c is the token ++ or -- */
4095 void inc(int post
, int c
)
4098 vdup(); /* save lvalue */
4100 gv_dup(); /* duplicate value */
4105 vpushi(c
- TOK_MID
);
4107 vstore(); /* store value */
4109 vpop(); /* if post op, return saved value */
4112 /* Parse GNUC __attribute__ extension. Currently, the following
4113 extensions are recognized:
4114 - aligned(n) : set data/function alignment.
4115 - section(x) : generate data/code in this section.
4116 - unused : currently ignored, but may be used someday.
4118 void parse_attribute(AttributeDef
*ad
)
4125 while (tok
!= ')') {
4126 if (tok
< TOK_IDENT
)
4127 expect("attribute name");
4132 case TOK___SECTION__
:
4135 expect("section name");
4136 ad
->section
= find_section(tokc
.ts
->str
);
4141 case TOK___ALIGNED__
:
4144 if (n
<= 0 || (n
& (n
- 1)) != 0)
4145 error("alignment must be a positive power of two");
4150 case TOK___UNUSED__
:
4151 /* currently, no need to handle it because tcc does not
4152 track unused objects */
4155 case TOK___NORETURN__
:
4156 /* currently, no need to handle it because tcc does not
4157 track unused objects */
4162 ad
->func_call
= FUNC_CDECL
;
4166 case TOK___STDCALL__
:
4167 ad
->func_call
= FUNC_STDCALL
;
4170 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4171 /* skip parameters */
4172 /* XXX: skip parenthesis too */
4175 while (tok
!= ')' && tok
!= -1)
4189 /* enum/struct/union declaration */
4190 int struct_decl(int u
)
4192 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4193 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4197 a
= tok
; /* save decl type */
4202 /* struct already defined ? return it */
4203 /* XXX: check consistency */
4204 s
= sym_find(v
| SYM_STRUCT
);
4207 error("invalid type");
4213 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4214 /* put struct/union/enum name in type */
4216 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4221 error("struct/union/enum already defined");
4222 /* cannot be empty */
4229 if (a
== TOK_ENUM
) {
4236 /* enum symbols have static storage */
4237 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4242 parse_btype(&b
, &ad
);
4247 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4248 if ((t
& VT_BTYPE
) == VT_FUNC
||
4249 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4250 error("invalid type for '%s'",
4251 get_tok_str(v
, NULL
));
4257 bit_size
= expr_const();
4258 /* XXX: handle v = 0 case for messages */
4260 error("negative width in bit-field '%s'",
4261 get_tok_str(v
, NULL
));
4262 if (v
&& bit_size
== 0)
4263 error("zero width for bit-field '%s'",
4264 get_tok_str(v
, NULL
));
4266 size
= type_size(t
, &align
);
4268 if (bit_size
>= 0) {
4273 error("bitfields must have scalar type");
4275 if (bit_size
> bsize
) {
4276 error("width of '%s' exceeds its type",
4277 get_tok_str(v
, NULL
));
4278 } else if (bit_size
== bsize
) {
4279 /* no need for bit fields */
4281 } else if (bit_size
== 0) {
4282 /* XXX: what to do if only padding in a
4284 /* zero size: means to pad */
4288 /* we do not have enough room ? */
4289 if ((bit_pos
+ bit_size
) > bsize
)
4292 /* XXX: handle LSB first */
4294 (bit_pos
<< VT_STRUCT_SHIFT
) |
4295 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4296 bit_pos
+= bit_size
;
4302 /* add new memory data only if starting
4304 if (lbit_pos
== 0) {
4305 if (a
== TOK_STRUCT
) {
4306 c
= (c
+ align
- 1) & -align
;
4314 if (align
> maxalign
)
4318 printf("add field %s offset=%d",
4319 get_tok_str(v
, NULL
), offset
);
4320 if (t
& VT_BITFIELD
) {
4321 printf(" pos=%d size=%d",
4322 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4323 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4327 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4331 if (tok
== ';' || tok
== -1)
4341 /* size for struct/union, dummy for enum */
4342 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4347 /* return 0 if no type declaration. otherwise, return the basic type
4350 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4352 int t
, u
, type_found
;
4355 memset(ad
, 0, sizeof(AttributeDef
));
4366 if ((t
& VT_BTYPE
) != 0)
4367 error("too many basic types");
4381 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4382 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4383 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4384 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4398 if ((t
& VT_BTYPE
) == VT_LONG
) {
4399 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4406 u
= struct_decl(VT_ENUM
);
4410 u
= struct_decl(VT_STRUCT
);
4413 /* type modifiers */
4418 case TOK___SIGNED__
:
4421 case TOK___INLINE__
:
4443 /* GNUC attribute */
4444 case TOK___ATTRIBUTE__
:
4445 parse_attribute(ad
);
4449 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4451 t
|= (s
->t
& ~VT_TYPEDEF
);
4458 /* long is never used as type */
4459 if ((t
& VT_BTYPE
) == VT_LONG
)
4460 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4465 int post_type(int t
, AttributeDef
*ad
)
4467 int p
, n
, pt
, l
, t1
;
4468 Sym
**plast
, *s
, *first
;
4472 /* function declaration */
4477 while (tok
!= ')') {
4478 /* read param name and compute offset */
4479 if (l
!= FUNC_OLD
) {
4480 if (!parse_btype(&pt
, &ad1
)) {
4482 error("invalid type");
4489 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4491 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4492 if ((pt
& VT_BTYPE
) == VT_VOID
)
4493 error("parameter declared as void");
4500 /* array must be transformed to pointer according to ANSI C */
4502 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4507 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4514 /* if no parameters, then old type prototype */
4518 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4519 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4520 /* we push a anonymous symbol which will contain the function prototype */
4522 s
= sym_push(p
, t
, ad
->func_call
, l
);
4524 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4525 } else if (tok
== '[') {
4526 /* array definition */
4532 error("invalid array size");
4535 /* parse next post type */
4536 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4537 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4539 /* we push a anonymous symbol which will contain the array
4542 sym_push(p
, t
, 0, n
);
4543 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4548 /* Read a type declaration (except basic type), and return the
4549 type. 'td' is a bitmask indicating which kind of type decl is
4550 expected. 't' should contain the basic type. 'ad' is the attribute
4551 definition of the basic type. It can be modified by type_decl(). */
4552 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4557 while (tok
== '*') {
4559 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4564 /* recursive type */
4565 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4568 /* XXX: this is not correct to modify 'ad' at this point, but
4569 the syntax is not clear */
4570 if (tok
== TOK___ATTRIBUTE__
)
4571 parse_attribute(ad
);
4572 u
= type_decl(ad
, v
, 0, td
);
4576 /* type identifier */
4577 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4581 if (!(td
& TYPE_ABSTRACT
))
4582 expect("identifier");
4586 /* append t at the end of u */
4587 t
= post_type(t
, ad
);
4588 if (tok
== TOK___ATTRIBUTE__
)
4589 parse_attribute(ad
);
4594 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4604 /* define a new external reference to a symbol 'v' of type 'u' */
4605 Sym
*external_sym(int v
, int u
, int r
)
4611 /* push forward reference */
4612 s
= sym_push1(&global_stack
,
4613 v
, u
| VT_EXTERN
, 0);
4614 s
->r
= r
| VT_CONST
| VT_SYM
;
4619 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4620 static int lvalue_type(int t
)
4627 else if (bt
== VT_SHORT
)
4631 if (t
& VT_UNSIGNED
)
4632 r
|= VT_LVAL_UNSIGNED
;
4636 /* indirection with full error checking and bound check */
4637 static void indir(void)
4639 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4641 if (vtop
->r
& VT_LVAL
)
4643 vtop
->t
= pointed_type(vtop
->t
);
4644 /* an array is never an lvalue */
4645 if (!(vtop
->t
& VT_ARRAY
)) {
4646 vtop
->r
|= lvalue_type(vtop
->t
);
4647 /* if bound checking, the referenced pointer must be checked */
4648 if (do_bounds_check
)
4649 vtop
->r
|= VT_MUSTBOUND
;
4653 /* pass a parameter to a function and do type checking and casting */
4654 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4657 func_type
= func
->c
;
4658 if (func_type
== FUNC_OLD
||
4659 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4660 /* default casting : only need to convert float to double */
4661 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4662 gen_cast(VT_DOUBLE
);
4663 } else if (arg
== NULL
) {
4664 error("too many arguments to function");
4666 gen_assign_cast(arg
->t
);
4673 int n
, t
, ft
, fc
, align
, size
, r
, data_offset
;
4678 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4681 } else if (tok
== TOK_CUINT
) {
4682 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4684 } else if (tok
== TOK_CLLONG
) {
4685 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4687 } else if (tok
== TOK_CULLONG
) {
4688 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4690 } else if (tok
== TOK_CFLOAT
) {
4691 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4693 } else if (tok
== TOK_CDOUBLE
) {
4694 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4696 } else if (tok
== TOK_CLDOUBLE
) {
4697 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4699 } else if (tok
== TOK___FUNC__
) {
4702 /* special function name identifier */
4704 len
= strlen(funcname
) + 1;
4705 /* generate char[len] type */
4706 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
4707 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4709 vpush_ref(t
, data_section
, data_section
->data_offset
);
4710 ptr
= section_ptr_add(data_section
, len
);
4711 memcpy(ptr
, funcname
, len
);
4713 } else if (tok
== TOK_LSTR
) {
4716 } else if (tok
== TOK_STR
) {
4717 /* string parsing */
4720 type_size(t
, &align
);
4721 data_offset
= data_section
->data_offset
;
4722 data_offset
= (data_offset
+ align
- 1) & -align
;
4724 /* we must declare it as an array first to use initializer parser */
4725 t
= VT_ARRAY
| mk_pointer(t
);
4726 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4727 data_offset
+= type_size(t
, &align
);
4728 /* XXX: is it correct to put it exactly as an array ? */
4729 vpush_ref(t
, data_section
, fc
);
4730 data_section
->data_offset
= data_offset
;
4736 if (parse_btype(&t
, &ad
)) {
4737 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4739 /* check ISOC99 compound literal */
4741 /* data is allocated locally by default */
4746 /* all except arrays are lvalues */
4747 if (!(ft
& VT_ARRAY
))
4748 r
|= lvalue_type(ft
);
4749 memset(&ad
, 0, sizeof(AttributeDef
));
4750 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4759 } else if (t
== '*') {
4762 } else if (t
== '&') {
4764 /* functions names must be treated as function pointers,
4765 except for unary '&' and sizeof. Since we consider that
4766 functions are not lvalues, we only have to handle it
4767 there and in function calls. */
4768 /* arrays can also be used although they are not lvalues */
4769 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4770 !(vtop
->t
& VT_ARRAY
))
4772 vtop
->t
= mk_pointer(vtop
->t
);
4777 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4778 vtop
->c
.i
= !vtop
->c
.i
;
4779 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4780 vtop
->c
.i
= vtop
->c
.i
^ 1;
4782 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4790 /* in order to force cast, we add zero */
4792 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
4793 error("pointer not accepted for unary plus");
4797 if (t
== TOK_SIZEOF
) {
4800 if (parse_btype(&t
, &ad
)) {
4801 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4803 /* XXX: some code could be generated: add eval
4815 vpushi(type_size(t
, &t
));
4817 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4820 } else if (t
== '-') {
4827 expect("identifier");
4831 error("'%s' undeclared", get_tok_str(t
, NULL
));
4832 /* for simple function calls, we tolerate undeclared
4833 external reference to int() function */
4834 s
= external_sym(t
, func_old_type
, 0);
4836 vset(s
->t
, s
->r
, s
->c
);
4837 /* if forward reference, we must point to s */
4838 if (vtop
->r
& VT_SYM
)
4843 /* post operations */
4845 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4848 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4850 if (tok
== TOK_ARROW
)
4855 /* expect pointer on structure */
4856 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4857 expect("struct or union");
4858 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4861 while ((s
= s
->next
) != NULL
) {
4866 error("field not found");
4867 /* add field offset to pointer */
4868 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4871 /* change type to field type, and set to lvalue */
4873 /* an array is never an lvalue */
4874 if (!(vtop
->t
& VT_ARRAY
))
4875 vtop
->r
|= lvalue_type(vtop
->t
);
4877 } else if (tok
== '[') {
4883 } else if (tok
== '(') {
4888 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4889 /* pointer test (no array accepted) */
4890 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4891 vtop
->t
= pointed_type(vtop
->t
);
4892 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4896 expect("function pointer");
4899 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4901 /* get return type */
4902 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4903 save_regs(0); /* save used temporary registers */
4904 gfunc_start(&gf
, s
->r
);
4906 sa
= s
->next
; /* first parameter */
4907 #ifdef INVERT_FUNC_PARAMS
4911 ParseState saved_parse_state
;
4914 /* read each argument and store it on a stack */
4915 /* XXX: merge it with macro args ? */
4921 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4925 else if (tok
== ')')
4927 tok_str_add_tok(&str
);
4930 tok_str_add(&str
, -1); /* end of file added */
4931 tok_str_add(&str
, 0);
4932 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4933 s1
->next
= sa
; /* add reference to argument */
4942 /* now generate code in reverse order by reading the stack */
4943 save_parse_state(&saved_parse_state
);
4945 macro_ptr
= (int *)args
->c
;
4949 expect("',' or ')'");
4950 gfunc_param_typed(&gf
, s
, args
->next
);
4952 free((int *)args
->c
);
4956 restore_parse_state(&saved_parse_state
);
4959 /* compute first implicit argument if a structure is returned */
4960 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4961 /* get some space for the returned structure */
4962 size
= type_size(s
->t
, &align
);
4963 loc
= (loc
- size
) & -align
;
4965 ret
.r
= VT_LOCAL
| VT_LVAL
;
4966 /* pass it as 'int' to avoid structure arg passing
4968 vset(VT_INT
, VT_LOCAL
, loc
);
4974 /* return in register */
4975 if (is_float(ret
.t
)) {
4978 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4984 #ifndef INVERT_FUNC_PARAMS
4988 gfunc_param_typed(&gf
, s
, sa
);
4998 error("too few arguments to function");
5002 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5016 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5017 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5018 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5041 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5042 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5043 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5044 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5045 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5046 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5047 (l
== 5 && tok
== '&') ||
5048 (l
== 6 && tok
== '^') ||
5049 (l
== 7 && tok
== '|') ||
5050 (l
== 8 && tok
== TOK_LAND
) ||
5051 (l
== 9 && tok
== TOK_LOR
)) {
5060 /* only used if non constant */
5068 if (tok
!= TOK_LAND
) {
5071 vset(VT_INT
, VT_JMPI
, t
);
5088 if (tok
!= TOK_LOR
) {
5091 vset(VT_INT
, VT_JMP
, t
);
5101 /* XXX: better constant handling */
5104 int t
, u
, c
, r1
, r2
, rc
;
5124 save_regs(1); /* we need to save all registers here except
5125 at the top because it is a branch point */
5128 /* XXX: long long handling ? */
5130 if (is_float(vtop
->t
))
5133 vtop
--; /* no vpop so that FP stack is not flushed */
5158 /* parse a constant expression and return value in vtop */
5159 void expr_const1(void)
5165 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5170 /* parse an integer constant and return its value */
5171 int expr_const(void)
5180 /* return the label token if current token is a label, otherwise
5187 /* fast test first */
5188 if (tok
< TOK_UIDENT
)
5190 /* no need to save tokc since we expect an identifier */
5198 /* XXX: may not work in all cases (macros ?) */
5207 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5212 /* generate line number info */
5214 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5215 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5217 last_line_num
= file
->line_num
;
5220 if (tok
== TOK_IF
) {
5227 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5229 if (c
== TOK_ELSE
) {
5233 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5234 gsym(d
); /* patch else jmp */
5237 } else if (tok
== TOK_WHILE
) {
5245 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5249 } else if (tok
== '{') {
5252 s
= local_stack
.top
;
5253 while (tok
!= '}') {
5256 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5258 /* pop locally defined symbols */
5259 sym_pop(&local_stack
, s
);
5261 } else if (tok
== TOK_RETURN
) {
5265 gen_assign_cast(func_vt
);
5266 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5267 /* if returning structure, must copy it to implicit
5268 first pointer arg location */
5269 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5272 /* copy structure value to pointer */
5274 } else if (is_float(func_vt
)) {
5279 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5282 rsym
= gjmp(rsym
); /* jmp */
5283 } else if (tok
== TOK_BREAK
) {
5286 error("cannot break");
5287 *bsym
= gjmp(*bsym
);
5290 } else if (tok
== TOK_CONTINUE
) {
5293 error("cannot continue");
5294 *csym
= gjmp(*csym
);
5297 } else if (tok
== TOK_FOR
) {
5324 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5329 if (tok
== TOK_DO
) {
5334 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5345 if (tok
== TOK_SWITCH
) {
5349 /* XXX: other types than integer */
5350 case_reg
= gv(RC_INT
);
5354 b
= gjmp(0); /* jump to first case */
5356 block(&a
, csym
, &b
, &c
, case_reg
);
5357 /* if no default, jmp after switch */
5365 if (tok
== TOK_CASE
) {
5372 if (gnu_ext
&& tok
== TOK_DOTS
) {
5376 warning("empty case range");
5378 /* since a case is like a label, we must skip it with a jmp */
5381 vset(VT_INT
, case_reg
, 0);
5385 *case_sym
= gtst(1, 0);
5388 *case_sym
= gtst(1, 0);
5389 vset(VT_INT
, case_reg
, 0);
5392 *case_sym
= gtst(1, *case_sym
);
5396 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5398 if (tok
== TOK_DEFAULT
) {
5404 error("too many 'default'");
5406 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5408 if (tok
== TOK_GOTO
) {
5410 s
= sym_find1(&label_stack
, tok
);
5411 /* put forward definition if needed */
5413 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5414 /* label already defined */
5415 if (s
->t
& LABEL_FORWARD
)
5425 s
= sym_find1(&label_stack
, b
);
5427 if (!(s
->t
& LABEL_FORWARD
))
5428 error("multiple defined label");
5433 sym_push1(&label_stack
, b
, 0, ind
);
5435 /* we accept this, but it is a mistake */
5437 warning("deprecated use of label at end of compound statement");
5439 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5441 /* expression case */
5451 /* t is the array or struct type. c is the array or struct
5452 address. cur_index/cur_field is the pointer to the current
5453 value. 'size_only' is true if only size info is needed (only used
5455 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5456 int *cur_index
, Sym
**cur_field
,
5460 int notfirst
, index
, align
, l
;
5463 if (gnu_ext
&& (l
= is_label()) != 0)
5466 while (tok
== '[' || tok
== '.') {
5468 if (!(t
& VT_ARRAY
))
5469 expect("array type");
5470 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5472 index
= expr_const();
5473 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5474 expect("invalid index");
5478 t
= pointed_type(t
);
5479 c
+= index
* type_size(t
, &align
);
5485 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5486 expect("struct/union type");
5487 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5499 t
= f
->t
| (t
& ~VT_TYPE
);
5514 t
= pointed_type(t
);
5515 c
+= index
* type_size(t
, &align
);
5519 error("too many field init");
5520 t
= f
->t
| (t
& ~VT_TYPE
);
5524 decl_initializer(t
, sec
, c
, 0, size_only
);
5528 #define EXPR_CONST 1
5531 /* store a value or an expression directly in global data or in local array */
5532 void init_putv(int t
, Section
*sec
, unsigned long c
,
5533 int v
, int expr_type
)
5535 int saved_global_expr
, bt
;
5543 /* compound literals must be allocated globally in this case */
5544 saved_global_expr
= global_expr
;
5547 global_expr
= saved_global_expr
;
5555 /* XXX: not portable */
5556 /* XXX: generate error if incorrect relocation */
5559 ptr
= sec
->data
+ c
;
5560 if ((vtop
->r
& VT_SYM
) &&
5566 error("initializer element is not computable at load time");
5569 *(char *)ptr
= vtop
->c
.i
;
5572 *(short *)ptr
= vtop
->c
.i
;
5575 *(double *)ptr
= vtop
->c
.d
;
5578 *(long double *)ptr
= vtop
->c
.ld
;
5581 *(long long *)ptr
= vtop
->c
.ll
;
5584 if (vtop
->r
& VT_SYM
) {
5585 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5588 *(int *)ptr
= vtop
->c
.i
;
5594 vset(t
, VT_LOCAL
, c
);
5601 /* put zeros for variable based init */
5602 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5607 /* nothing to do because globals are already set to zero */
5609 gfunc_start(&gf
, FUNC_CDECL
);
5614 vset(VT_INT
, VT_LOCAL
, c
);
5616 vpush_sym(func_old_type
, TOK_memset
);
5621 /* 't' contains the type and storage info. 'c' is the offset of the
5622 object in section 'sec'. If 'sec' is NULL, it means stack based
5623 allocation. 'first' is true if array '{' must be read (multi
5624 dimension implicit array init handling). 'size_only' is true if
5625 size only evaluation is wanted (only for arrays). */
5626 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5628 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5629 int t1
, size1
, align1
, expr_type
;
5634 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5637 t1
= pointed_type(t
);
5638 size1
= type_size(t1
, &align1
);
5641 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5647 /* only parse strings here if correct type (otherwise: handle
5648 them as ((w)char *) expressions */
5649 if ((tok
== TOK_LSTR
&&
5650 (t1
& VT_BTYPE
) == VT_INT
) ||
5652 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5653 /* XXX: move multiple string parsing in parser ? */
5654 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5656 /* compute maximum number of chars wanted */
5658 if (n
>= 0 && nb
> (n
- array_length
))
5659 nb
= n
- array_length
;
5662 warning("initializer-string for array is too long");
5664 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5665 ts
->str
[i
], EXPR_VAL
);
5671 /* only add trailing zero if enough storage (no
5672 warning in this case since it is standard) */
5673 if (n
< 0 || array_length
< n
) {
5675 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5681 while (tok
!= '}') {
5682 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5683 if (n
>= 0 && index
>= n
)
5684 error("index too large");
5685 /* must put zero in holes (note that doing it that way
5686 ensures that it even works with designators) */
5687 if (!size_only
&& array_length
< index
) {
5688 init_putz(t1
, sec
, c
+ array_length
* size1
,
5689 (index
- array_length
) * size1
);
5692 if (index
> array_length
)
5693 array_length
= index
;
5694 /* special test for multi dimensional arrays (may not
5695 be strictly correct if designators are used at the
5697 if (index
>= n
&& no_oblock
)
5706 /* put zeros at the end */
5707 if (!size_only
&& n
>= 0 && array_length
< n
) {
5708 init_putz(t1
, sec
, c
+ array_length
* size1
,
5709 (n
- array_length
) * size1
);
5711 /* patch type size if needed */
5713 s
->c
= array_length
;
5714 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5715 /* XXX: union needs only one init */
5717 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5722 while (tok
!= '}') {
5723 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5724 /* fill with zero between fields */
5726 if (!size_only
&& array_length
< index
) {
5727 init_putz(t
, sec
, c
+ array_length
,
5728 index
- array_length
);
5730 index
= index
+ type_size(f
->t
, &align1
);
5731 if (index
> array_length
)
5732 array_length
= index
;
5738 /* put zeros at the end */
5739 if (!size_only
&& array_length
< n
) {
5740 init_putz(t
, sec
, c
+ array_length
,
5744 } else if (tok
== '{') {
5746 decl_initializer(t
, sec
, c
, first
, size_only
);
5748 } else if (size_only
) {
5749 /* just skip expression */
5751 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5755 else if (tok
== ')')
5760 /* currently, we always use constant expression for globals
5761 (may change for scripting case) */
5762 expr_type
= EXPR_CONST
;
5764 expr_type
= EXPR_ANY
;
5765 init_putv(t
, sec
, c
, 0, expr_type
);
5769 /* parse an initializer for type 't' if 'has_init' is true, and
5770 allocate space in local or global data space ('r' is either
5771 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5772 variable 'v' of scope 'scope' is declared before initializers are
5773 parsed. If 'v' is zero, then a reference to the new object is put
5774 in the value stack. */
5775 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5778 int size
, align
, addr
, data_offset
;
5780 ParseState saved_parse_state
;
5781 TokenString init_str
;
5784 size
= type_size(t
, &align
);
5785 /* If unknown size, we must evaluate it before
5786 evaluating initializers because
5787 initializers can generate global data too
5788 (e.g. string pointers or ISOC99 compound
5789 literals). It also simplifies local
5790 initializers handling */
5791 tok_str_new(&init_str
);
5794 error("unknown type size");
5795 /* get all init string */
5797 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5799 error("unexpected end of file in initializer");
5800 tok_str_add_tok(&init_str
);
5803 else if (tok
== '}') {
5810 tok_str_add(&init_str
, -1);
5811 tok_str_add(&init_str
, 0);
5814 save_parse_state(&saved_parse_state
);
5816 macro_ptr
= init_str
.str
;
5818 decl_initializer(t
, NULL
, 0, 1, 1);
5819 /* prepare second initializer parsing */
5820 macro_ptr
= init_str
.str
;
5823 /* if still unknown size, error */
5824 size
= type_size(t
, &align
);
5826 error("unknown type size");
5828 /* take into account specified alignment if bigger */
5829 if (ad
->aligned
> align
)
5830 align
= ad
->aligned
;
5831 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5833 if (do_bounds_check
&& (t
& VT_ARRAY
))
5835 #ifdef TCC_TARGET_IL
5836 /* XXX: ugly patch to allocate local variables for IL, just
5841 loc
= (loc
- size
) & -align
;
5844 /* handles bounds */
5845 /* XXX: currently, since we do only one pass, we cannot track
5846 '&' operators, so we add only arrays */
5847 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5848 unsigned long *bounds_ptr
;
5849 /* add padding between regions */
5851 /* then add local bound info */
5852 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
5853 bounds_ptr
[0] = addr
;
5854 bounds_ptr
[1] = size
;
5857 /* compute section */
5865 data_offset
= sec
->data_offset
;
5866 data_offset
= (data_offset
+ align
- 1) & -align
;
5868 /* very important to increment global pointer at this time
5869 because initializers themselves can create new initializers */
5870 data_offset
+= size
;
5871 /* add padding if bound check */
5872 if (do_bounds_check
)
5874 sec
->data_offset
= data_offset
;
5878 /* local variable */
5879 sym_push(v
, t
, r
, addr
);
5881 /* push local reference */
5888 if (scope
== VT_CONST
) {
5889 /* global scope: see if already defined */
5893 if (!is_compatible_types(sym
->t
, t
))
5894 error("incompatible types for redefinition of '%s'",
5895 get_tok_str(v
, NULL
));
5896 if (!(sym
->t
& VT_EXTERN
))
5897 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5898 sym
->t
&= ~VT_EXTERN
;
5901 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5903 put_extern_sym(sym
, sec
, addr
);
5907 /* push global reference */
5908 sym
= get_sym_ref(t
, sec
, addr
, 0);
5910 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
5913 /* handles bounds now because the symbol must be defined
5914 before for the relocation */
5915 if (do_bounds_check
) {
5916 unsigned long *bounds_ptr
;
5918 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
5919 /* then add global bound info */
5920 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
5921 bounds_ptr
[0] = 0; /* relocated */
5922 bounds_ptr
[1] = size
;
5926 decl_initializer(t
, sec
, addr
, 1, 0);
5927 /* restore parse state if needed */
5930 restore_parse_state(&saved_parse_state
);
5935 void put_func_debug(Sym
*sym
)
5940 /* XXX: we put here a dummy type */
5941 snprintf(buf
, sizeof(buf
), "%s:%c1",
5942 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
5943 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
5944 cur_text_section
, sym
->c
);
5950 /* not finished : try to put some local vars in registers */
5951 //#define CONFIG_REG_VARS
5953 #ifdef CONFIG_REG_VARS
5954 void add_var_ref(int t
)
5956 printf("%s:%d: &%s\n",
5957 file
->filename
, file
->line_num
,
5958 get_tok_str(t
, NULL
));
5961 /* first pass on a function with heuristic to extract variable usage
5962 and pointer references to local variables for register allocation */
5963 void analyse_function(void)
5970 /* any symbol coming after '&' is considered as being a
5971 variable whose reference is taken. It is highly unaccurate
5972 but it is difficult to do better without a complete parse */
5975 /* if '& number', then no need to examine next tokens */
5976 if (tok
== TOK_CINT
||
5978 tok
== TOK_CLLONG
||
5979 tok
== TOK_CULLONG
) {
5981 } else if (tok
>= TOK_UIDENT
) {
5982 /* if '& ident [' or '& ident ->', then ident address
5986 if (tok
!= '[' && tok
!= TOK_ARROW
)
5990 while (tok
!= '}' && tok
!= ';' &&
5991 !((tok
== ',' || tok
== ')') && level
== 0)) {
5992 if (tok
>= TOK_UIDENT
) {
5994 } else if (tok
== '(') {
5996 } else if (tok
== ')') {
6009 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6012 int t
, b
, v
, has_init
, r
;
6017 if (!parse_btype(&b
, &ad
)) {
6018 /* skip redundant ';' */
6019 /* XXX: find more elegant solution */
6024 /* special test for old K&R protos without explicit int
6025 type. Only accepted when defining global data */
6026 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6030 if (((b
& VT_BTYPE
) == VT_ENUM
||
6031 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6033 /* we accept no variable after */
6037 while (1) { /* iterate thru each declaration */
6038 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6042 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6043 printf("type = '%s'\n", buf
);
6047 #ifdef CONFIG_REG_VARS
6048 TokenString func_str
;
6049 ParseState saved_parse_state
;
6054 error("cannot use local functions");
6056 expect("function definition");
6058 #ifdef CONFIG_REG_VARS
6059 /* parse all function code and record it */
6061 tok_str_new(&func_str
);
6067 error("unexpected end of file");
6068 tok_str_add_tok(&func_str
);
6073 } else if (t
== '}') {
6075 if (block_level
== 0)
6079 tok_str_add(&func_str
, -1);
6080 tok_str_add(&func_str
, 0);
6082 save_parse_state(&saved_parse_state
);
6084 macro_ptr
= func_str
.str
;
6089 /* compute text section */
6090 cur_text_section
= ad
.section
;
6091 if (!cur_text_section
)
6092 cur_text_section
= text_section
;
6093 ind
= cur_text_section
->data_offset
;
6094 funcname
= get_tok_str(v
, NULL
);
6097 /* if symbol is already defined, then put complete type */
6100 /* put function symbol */
6101 sym
= sym_push1(&global_stack
, v
, t
, 0);
6103 put_extern_sym(sym
, cur_text_section
, ind
);
6104 sym
->r
= VT_SYM
| VT_CONST
;
6105 /* put debug symbol */
6107 put_func_debug(sym
);
6108 /* push a dummy symbol to enable local sym storage */
6109 sym_push1(&local_stack
, 0, 0, 0);
6113 #ifdef CONFIG_REG_VARS
6114 macro_ptr
= func_str
.str
;
6117 block(NULL
, NULL
, NULL
, NULL
, 0);
6120 cur_text_section
->data_offset
= ind
;
6121 sym_pop(&label_stack
, NULL
); /* reset label stack */
6122 sym_pop(&local_stack
, NULL
); /* reset local stack */
6123 /* end of function */
6125 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6127 funcname
= ""; /* for safety */
6128 func_vt
= VT_VOID
; /* for safety */
6129 ind
= 0; /* for safety */
6131 #ifdef CONFIG_REG_VARS
6133 restore_parse_state(&saved_parse_state
);
6137 if (b
& VT_TYPEDEF
) {
6138 /* save typedefed type */
6139 /* XXX: test storage specifiers ? */
6140 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6141 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6142 /* external function definition */
6143 external_sym(v
, t
, 0);
6145 /* not lvalue if array */
6147 if (!(t
& VT_ARRAY
))
6148 r
|= lvalue_type(t
);
6149 if (b
& VT_EXTERN
) {
6150 /* external variable */
6151 external_sym(v
, t
, r
);
6157 has_init
= (tok
== '=');
6160 decl_initializer_alloc(t
, &ad
, r
,
6174 /* compile the C file opened in 'file'. Return non zero if errors. */
6175 static int tcc_compile(TCCState
*s
)
6182 include_stack_ptr
= include_stack
;
6183 ifdef_stack_ptr
= ifdef_stack
;
6186 anon_sym
= SYM_FIRST_ANOM
;
6188 /* file info: full path + filename */
6189 section_sym
= 0; /* avoid warning */
6191 section_sym
= put_elf_sym(symtab_section
, 0, 0,
6192 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
6193 text_section
->sh_num
, NULL
);
6194 getcwd(buf
, sizeof(buf
));
6195 pstrcat(buf
, sizeof(buf
), "/");
6196 put_stabs_r(buf
, N_SO
, 0, 0,
6197 text_section
->data_offset
, text_section
, section_sym
);
6198 put_stabs_r(file
->filename
, N_SO
, 0, 0,
6199 text_section
->data_offset
, text_section
, section_sym
);
6201 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6202 symbols can be safely used */
6203 put_elf_sym(symtab_section
, 0, 0,
6204 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6205 SHN_ABS
, file
->filename
);
6207 /* define common 'char *' type because it is often used internally
6208 for arrays and struct dereference */
6209 char_pointer_type
= mk_pointer(VT_BYTE
);
6210 /* define an old type function 'int func()' */
6212 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
6213 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6215 define_start
= define_stack
.top
;
6217 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6221 expect("declaration");
6223 /* end of translation unit info */
6225 put_stabs_r(NULL
, N_SO
, 0, 0,
6226 text_section
->data_offset
, text_section
, section_sym
);
6229 /* reset define stack, but leave -Dsymbols (may be incorrect if
6230 they are undefined) */
6231 sym_pop(&define_stack
, define_start
);
6233 sym_pop(&global_stack
, NULL
);
6238 int tcc_compile_string(TCCState
*s
, const char *str
)
6240 BufferedFile bf1
, *bf
= &bf1
;
6243 /* init file structure */
6245 bf
->buf_ptr
= (char *)str
;
6246 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6247 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6251 ret
= tcc_compile(s
);
6253 /* currently, no need to close */
6257 /* define a symbol. A value can also be provided with the '=' operator */
6258 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6260 BufferedFile bf1
, *bf
= &bf1
;
6262 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6263 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6267 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6269 /* init file structure */
6271 bf
->buf_ptr
= bf
->buffer
;
6272 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6273 bf
->filename
[0] = '\0';
6277 include_stack_ptr
= include_stack
;
6279 /* parse with define parser */
6281 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6287 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6291 ts
= tok_alloc(sym
, 0);
6292 s
= sym_find1(&define_stack
, tok
);
6293 /* undefine symbol by putting an invalid name */
6295 sym_undef(&define_stack
, s
);
6298 static int put_elf_str(Section
*s
, const char *sym
)
6303 len
= strlen(sym
) + 1;
6304 offset
= s
->data_offset
;
6305 ptr
= section_ptr_add(s
, len
);
6306 memcpy(ptr
, sym
, len
);
6310 /* elf symbol hashing function */
6311 static unsigned long elf_hash(const unsigned char *name
)
6313 unsigned long h
= 0, g
;
6316 h
= (h
<< 4) + *name
++;
6325 /* return the symbol number */
6326 static int put_elf_sym(Section
*s
,
6327 unsigned long value
, unsigned long size
,
6328 int info
, int other
, int shndx
, const char *name
)
6330 int name_offset
, sym_index
;
6335 sym
= section_ptr_add(s
, sizeof(Elf32_Sym
));
6337 name_offset
= put_elf_str(s
->link
, name
);
6340 /* XXX: endianness */
6341 sym
->st_name
= name_offset
;
6342 sym
->st_value
= value
;
6343 sym
->st_size
= size
;
6344 sym
->st_info
= info
;
6345 sym
->st_other
= other
;
6346 sym
->st_shndx
= shndx
;
6347 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6351 ptr
= section_ptr_add(hs
, sizeof(int));
6352 /* only add global or weak symbols */
6353 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
6354 /* add another hashing entry */
6355 nbuckets
= ((int *)hs
->data
)[0];
6356 h
= elf_hash(name
) % nbuckets
;
6357 *ptr
= ((int *)hs
->data
)[2 + h
];
6358 ((int *)hs
->data
)[2 + h
] = sym_index
;
6362 /* but still add room for all symbols */
6363 ((int *)hs
->data
)[1]++;
6368 /* find global ELF symbol 'name' and return its index. Return 0 if not
6370 static int find_elf_sym(Section
*s
, const char *name
)
6374 int nbuckets
, sym_index
, h
;
6380 nbuckets
= ((int *)hs
->data
)[0];
6381 h
= elf_hash(name
) % nbuckets
;
6382 sym_index
= ((int *)hs
->data
)[2 + h
];
6383 while (sym_index
!= 0) {
6384 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6385 name1
= s
->link
->data
+ sym
->st_name
;
6386 if (!strcmp(name
, name1
))
6388 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6393 /* return elf symbol value or error */
6394 static unsigned long get_elf_sym_val(const char *name
)
6399 sym_index
= find_elf_sym(symtab_section
, name
);
6401 error("%s not defined", name
);
6402 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6403 return sym
->st_value
;
6406 /* add an elf symbol : check if it is already defined and patch
6407 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6408 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
6409 int info
, int sh_num
, const char *name
)
6412 int sym_bind
, sym_index
, sym_type
, esym_bind
;
6414 sym_bind
= ELF32_ST_BIND(info
);
6415 sym_type
= ELF32_ST_TYPE(info
);
6417 if (sym_bind
!= STB_LOCAL
) {
6418 /* we search global or weak symbols */
6419 sym_index
= find_elf_sym(s
, name
);
6422 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6423 if (esym
->st_shndx
!= SHN_UNDEF
) {
6424 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
6425 if (sh_num
== SHN_UNDEF
) {
6426 /* ignore adding of undefined symbol if the
6427 corresponding symbol is already defined */
6428 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
6429 /* global overrides weak, so patch */
6431 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
6432 /* weak is ignored if already global */
6435 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6436 sym_bind
, sh_num
, esym_bind
, esym
->st_shndx
);
6438 /* NOTE: we accept that two DLL define the same symbol */
6439 if (s
!= dynsymtab_section
)
6440 error("'%s' defined twice", name
);
6444 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6445 esym
->st_shndx
= sh_num
;
6446 esym
->st_value
= value
;
6447 esym
->st_size
= size
;
6451 sym_index
= put_elf_sym(s
, value
, size
,
6452 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6458 /* update sym->c so that it points to an external symbol in section
6459 'section' with value 'value' */
6460 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
)
6462 int sym_type
, sym_bind
, sh_num
, info
;
6468 sh_num
= section
->sh_num
;
6472 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6473 sym_type
= STT_FUNC
;
6475 sym_type
= STT_OBJECT
;
6476 if (sym
->t
& VT_STATIC
)
6477 sym_bind
= STB_LOCAL
;
6479 sym_bind
= STB_GLOBAL
;
6481 name
= get_tok_str(sym
->v
, NULL
);
6482 #ifdef CONFIG_TCC_BCHECK
6483 if (do_bounds_check
) {
6484 /* if bound checking is activated, we change some function
6485 names by adding the "__bound" prefix */
6497 strcpy(buf
, "__bound_");
6504 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6505 sym
->c
= add_elf_sym(symtab_section
, value
, 0, info
, sh_num
, name
);
6507 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6508 esym
->st_value
= value
;
6509 esym
->st_shndx
= sh_num
;
6513 /* put relocation */
6514 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
6515 int type
, int symbol
)
6523 /* if no relocation section, create it */
6524 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6525 /* if the symtab is allocated, then we consider the relocation
6527 sr
= new_section(buf
, SHT_REL
, symtab
->sh_flags
);
6528 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6530 sr
->sh_info
= s
->sh_num
;
6533 rel
= section_ptr_add(sr
, sizeof(Elf32_Rel
));
6534 rel
->r_offset
= offset
;
6535 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6538 /* put stab debug information */
6541 unsigned long n_strx
; /* index into string table of name */
6542 unsigned char n_type
; /* type of symbol */
6543 unsigned char n_other
; /* misc info (usually empty) */
6544 unsigned short n_desc
; /* description field */
6545 unsigned long n_value
; /* value of symbol */
6548 static void put_stabs(const char *str
, int type
, int other
, int desc
,
6549 unsigned long value
)
6553 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
6555 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6560 sym
->n_other
= other
;
6562 sym
->n_value
= value
;
6565 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
6566 unsigned long value
, Section
*sec
, int sym_index
)
6568 put_stabs(str
, type
, other
, desc
, value
);
6569 put_elf_reloc(symtab_section
, stab_section
,
6570 stab_section
->data_offset
- sizeof(unsigned long),
6571 R_DATA_32
, sym_index
);
6574 static void put_stabn(int type
, int other
, int desc
, int value
)
6576 put_stabs(NULL
, type
, other
, desc
, value
);
6579 static void put_stabd(int type
, int other
, int desc
)
6581 put_stabs(NULL
, type
, other
, desc
, 0);
6584 /* In an ELF file symbol table, the local symbols must appear below
6585 the global and weak ones. Since TCC cannot sort it while generating
6586 the code, we must do it after. All the relocation tables are also
6587 modified to take into account the symbol table sorting */
6588 static void sort_syms(Section
*s
)
6590 int *old_to_new_syms
;
6591 Elf32_Sym
*new_syms
;
6594 Elf32_Rel
*rel
, *rel_end
;
6596 int type
, sym_index
;
6598 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
6599 new_syms
= malloc(nb_syms
* sizeof(Elf32_Sym
));
6601 error("memory full");
6602 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
6603 if (!old_to_new_syms
)
6604 error("memory full");
6605 /* first pass for local symbols */
6606 p
= (Elf32_Sym
*)s
->data
;
6608 for(i
= 0; i
< nb_syms
; i
++) {
6609 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
6610 old_to_new_syms
[i
] = q
- new_syms
;
6615 /* save the number of local symbols in section header */
6616 s
->sh_info
= q
- new_syms
;
6618 /* then second pass for non local symbols */
6619 p
= (Elf32_Sym
*)s
->data
;
6620 for(i
= 0; i
< nb_syms
; i
++) {
6621 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
6622 old_to_new_syms
[i
] = q
- new_syms
;
6628 /* we copy the new symbols to the old */
6629 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
6632 /* now we modify all the relocations */
6633 for(i
= 1; i
< nb_sections
; i
++) {
6635 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
6636 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6637 for(rel
= (Elf32_Rel
*)sr
->data
;
6640 sym_index
= ELF32_R_SYM(rel
->r_info
);
6641 type
= ELF32_R_TYPE(rel
->r_info
);
6642 sym_index
= old_to_new_syms
[sym_index
];
6643 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
6648 free(old_to_new_syms
);
6651 /* relocate common symbols in the .bss section */
6652 static void relocate_common_syms(void)
6654 Elf32_Sym
*sym
, *sym_end
;
6655 unsigned long offset
, align
;
6657 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
6658 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6661 if (sym
->st_shndx
== SHN_COMMON
) {
6663 align
= sym
->st_value
;
6664 offset
= bss_section
->data_offset
;
6665 offset
= (offset
+ align
- 1) & -align
;
6666 sym
->st_value
= offset
;
6667 sym
->st_shndx
= bss_section
->sh_num
;
6668 offset
+= sym
->st_size
;
6669 bss_section
->data_offset
= offset
;
6674 static void *resolve_sym(const char *sym
)
6676 return dlsym(NULL
, sym
);
6679 /* relocate symbol table, resolve undefined symbols if do_resolve is
6680 true and output error if undefined symbol. */
6681 static void relocate_syms(int do_resolve
)
6683 Elf32_Sym
*sym
, *esym
, *sym_end
;
6684 int sym_bind
, sh_num
, sym_index
;
6688 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
6689 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6692 sh_num
= sym
->st_shndx
;
6693 if (sh_num
== SHN_UNDEF
) {
6694 name
= strtab_section
->data
+ sym
->st_name
;
6696 name
= symtab_section
->link
->data
+ sym
->st_name
;
6697 addr
= (unsigned long)resolve_sym(name
);
6699 sym
->st_value
= addr
;
6702 } else if (dynsym
) {
6703 /* if dynamic symbol exist, then use it */
6704 sym_index
= find_elf_sym(dynsym
, name
);
6706 esym
= &((Elf32_Sym
*)dynsym
->data
)[sym_index
];
6707 sym
->st_value
= esym
->st_value
;
6711 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
6713 if (!strcmp(name
, "_fp_hw"))
6715 /* only weak symbols are accepted to be undefined. Their
6717 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
6718 if (sym_bind
== STB_WEAK
) {
6721 error("undefined symbol '%s'", name
);
6723 } else if (sh_num
< SHN_LORESERVE
) {
6724 /* add section base */
6725 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
6731 /* elf relocation, CPU dependant */
6732 static void elf_reloc(unsigned char *ptr
,
6733 unsigned long addr
, unsigned long val
, int type
,
6742 *(int *)ptr
+= val
- addr
;
6744 case R_386_GLOB_DAT
:
6745 case R_386_JMP_SLOT
:
6749 *(int *)ptr
+= got
->sh_addr
- addr
;
6752 *(int *)ptr
+= val
- got
->sh_addr
;
6755 /* we load the got offset */
6756 *(int *)ptr
+= got_offsets
[sym_index
];
6762 /* relocate a given section */
6763 static void relocate_section(Section
*s
)
6766 Elf32_Rel
*rel
, *rel_end
;
6768 int type
, sym_index
;
6773 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6774 for(rel
= (Elf32_Rel
*)sr
->data
;
6777 ptr
= s
->data
+ rel
->r_offset
;
6779 sym_index
= ELF32_R_SYM(rel
->r_info
);
6780 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6781 val
= sym
->st_value
;
6782 type
= ELF32_R_TYPE(rel
->r_info
);
6783 elf_reloc(ptr
, s
->sh_addr
+ rel
->r_offset
, val
, type
, sym_index
);
6787 /* relocate relocation table in 'sr' */
6788 static void relocate_rel(Section
*sr
)
6791 Elf32_Rel
*rel
, *rel_end
;
6793 s
= sections
[sr
->sh_info
];
6794 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6795 for(rel
= (Elf32_Rel
*)sr
->data
;
6798 rel
->r_offset
+= s
->sh_addr
;
6802 static void put_got_offset(int index
, unsigned long val
)
6807 if (index
>= nb_got_offsets
) {
6808 /* find immediately bigger power of 2 and reallocate array */
6812 tab
= realloc(got_offsets
, n
* sizeof(unsigned long));
6814 error("memory full");
6816 memset(got_offsets
+ nb_got_offsets
, 0,
6817 (n
- nb_got_offsets
) * sizeof(unsigned long));
6820 got_offsets
[index
] = val
;
6823 /* XXX: suppress that */
6824 static void put32(unsigned char *p
, unsigned int val
)
6832 static void build_got(void)
6836 /* if no got, then create it */
6837 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6838 got
->sh_entsize
= 4;
6839 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
6840 got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
6841 ptr
= section_ptr_add(got
, 3 * sizeof(int));
6842 /* keep space for _DYNAMIC pointer, if present */
6844 /* two dummy got entries */
6849 /* put a got entry corresponding to a symbol in symtab_section. 'size'
6850 and 'info' can be modifed if more precise info comes from the DLL */
6851 static void put_got_entry(int reloc_type
, unsigned long size
, int info
,
6857 unsigned long offset
;
6863 /* if a got entry already exists for that symbol, no need to add one */
6864 if (sym_index
< nb_got_offsets
&&
6865 got_offsets
[sym_index
] != 0)
6868 put_got_offset(sym_index
, got
->data_offset
);
6871 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6872 name
= symtab_section
->link
->data
+ sym
->st_name
;
6873 offset
= sym
->st_value
;
6874 /* NOTE: we put temporarily the got offset */
6875 if (reloc_type
== R_386_JMP_SLOT
) {
6877 offset
= got
->data_offset
;
6879 index
= put_elf_sym(dynsym
, offset
,
6880 size
, info
, 0, sym
->st_shndx
, name
);
6881 /* put a got entry */
6882 put_elf_reloc(dynsym
, got
,
6886 ptr
= section_ptr_add(got
, sizeof(int));
6890 /* build GOT and PLT entries */
6891 static void build_got_entries(void)
6893 Section
*s
, *symtab
;
6894 Elf32_Rel
*rel
, *rel_end
;
6896 int i
, type
, reloc_type
, sym_index
;
6898 for(i
= 1; i
< nb_sections
; i
++) {
6900 if (s
->sh_type
!= SHT_REL
)
6902 /* no need to handle got relocations */
6903 if (s
->link
!= symtab_section
)
6906 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
6907 for(rel
= (Elf32_Rel
*)s
->data
;
6910 type
= ELF32_R_TYPE(rel
->r_info
);
6918 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
6919 sym_index
= ELF32_R_SYM(rel
->r_info
);
6920 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6921 /* look at the symbol got offset. If none, then add one */
6922 if (type
== R_386_GOT32
)
6923 reloc_type
= R_386_GLOB_DAT
;
6925 reloc_type
= R_386_JMP_SLOT
;
6926 put_got_entry(reloc_type
, sym
->st_size
, sym
->st_info
,
6937 static Section
*new_section_hash(const char *name
, int sh_flags
,
6938 int nb_buckets
, Section
*symtab
)
6941 hash
= new_section(name
, SHT_HASH
, sh_flags
);
6942 ((int *)hash
->data
)[0] = nb_buckets
;
6943 ((int *)hash
->data
)[1] = 1;
6944 hash
->sh_entsize
= sizeof(int);
6945 section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
6946 symtab
->hash
= hash
;
6947 hash
->link
= symtab
;
6951 /* put dynamic tag */
6952 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
6955 dyn
= section_ptr_add(dynamic
, sizeof(Elf32_Dyn
));
6957 dyn
->d_un
.d_val
= val
;
6960 /* add tcc runtime libraries */
6961 static void tcc_add_runtime(TCCState
*s1
)
6966 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.o");
6967 tcc_add_file(s1
, buf
);
6968 #ifdef CONFIG_TCC_BCHECK
6969 if (do_bounds_check
) {
6970 /* XXX: add an object file to do that */
6971 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
6973 add_elf_sym(symtab_section
, 0, 0,
6974 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6975 bounds_section
->sh_num
, "__bounds_start");
6976 add_elf_sym(symtab_section
, (long)&rt_error
, 0,
6977 ELF32_ST_INFO(STB_GLOBAL
, STT_FUNC
),
6978 SHN_ABS
, "rt_error");
6979 /* add bound check code */
6980 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
6981 tcc_add_file(s1
, buf
);
6984 /* add libc if not memory output */
6985 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
6986 tcc_add_library(s1
, "c");
6987 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
6989 /* add various standard linker symbols */
6990 add_elf_sym(symtab_section
,
6991 text_section
->data_offset
, 0,
6992 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6993 text_section
->sh_num
, "_etext");
6994 add_elf_sym(symtab_section
,
6995 data_section
->data_offset
, 0,
6996 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6997 data_section
->sh_num
, "_edata");
6998 add_elf_sym(symtab_section
,
6999 bss_section
->data_offset
, 0,
7000 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7001 bss_section
->sh_num
, "_end");
7004 /* add dynamic sections so that the executable is dynamically linked */
7005 static char elf_interp
[] = "/lib/ld-linux.so.2";
7007 #define ELF_START_ADDR 0x08048000
7008 #define ELF_PAGE_SIZE 0x1000
7010 /* output an ELF file */
7011 /* XXX: handle realloc'ed sections (instead of mmaping them) */
7012 /* XXX: suppress unneeded sections */
7013 int tcc_output_file(TCCState
*s1
, const char *filename
)
7019 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
7021 Section
*strsec
, *s
;
7022 Elf32_Shdr shdr
, *sh
;
7023 Elf32_Phdr
*phdr
, *ph
;
7024 Section
*interp
, *plt
, *dynamic
, *dynstr
, *hash
;
7025 unsigned long saved_dynamic_data_offset
;
7027 int type
, file_type
;
7028 unsigned long rel_addr
, rel_size
;
7030 file_type
= s1
->output_type
;
7032 if (file_type
!= TCC_OUTPUT_OBJ
)
7033 tcc_add_runtime(s1
);
7040 plt
= NULL
; /* avoid warning */
7041 hash
= NULL
; /* avoid warning */
7042 dynstr
= NULL
; /* avoid warning */
7043 saved_dynamic_data_offset
= 0; /* avoid warning */
7045 if (file_type
!= TCC_OUTPUT_OBJ
) {
7047 relocate_common_syms();
7051 int sym_index
, index
;
7052 Elf32_Sym
*esym
, *sym_end
;
7054 if (file_type
== TCC_OUTPUT_EXE
) {
7056 /* add interpreter section only if executable */
7057 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
7058 interp
->sh_addralign
= 1;
7059 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
7060 strcpy(ptr
, elf_interp
);
7063 /* add dynamic symbol table */
7064 dynsym
= new_section(".dynsym", SHT_DYNSYM
, SHF_ALLOC
);
7065 dynsym
->sh_entsize
= sizeof(Elf32_Sym
);
7066 dynstr
= new_section(".dynstr", SHT_STRTAB
, SHF_ALLOC
);
7067 put_elf_str(dynstr
, "");
7068 dynsym
->link
= dynstr
;
7069 put_elf_sym(dynsym
, 0, 0, 0, 0, 0, NULL
);
7072 hash
= new_section_hash(".hash", SHF_ALLOC
,
7073 ELF_DYNSYM_HASH_SIZE
, dynsym
);
7075 /* add dynamic section */
7076 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
7077 SHF_ALLOC
| SHF_WRITE
);
7078 dynamic
->link
= dynstr
;
7079 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
7082 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7083 plt
->sh_entsize
= 4;
7085 /* scan for undefined symbols and see if they are in the
7086 dynamic symbols. If a symbol STT_FUNC is found, then we
7087 add it in the PLT. If a symbol STT_OBJECT is found, we
7088 add it in the .bss section with a suitable relocation */
7089 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
7090 symtab_section
->data_offset
);
7091 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7094 if (sym
->st_shndx
== SHN_UNDEF
) {
7095 name
= symtab_section
->link
->data
+ sym
->st_name
;
7096 sym_index
= find_elf_sym(dynsymtab_section
, name
);
7098 esym
= &((Elf32_Sym
*)dynsymtab_section
->data
)[sym_index
];
7099 type
= ELF32_ST_TYPE(esym
->st_info
);
7100 if (type
== STT_FUNC
) {
7101 put_got_entry(R_386_JMP_SLOT
, esym
->st_size
,
7103 sym
- (Elf32_Sym
*)symtab_section
->data
);
7104 } else if (type
== STT_OBJECT
) {
7105 unsigned long offset
;
7106 offset
= bss_section
->data_offset
;
7107 /* XXX: which alignment ? */
7108 offset
= (offset
+ 8 - 1) & -8;
7109 index
= put_elf_sym(dynsym
, offset
, esym
->st_size
,
7111 bss_section
->sh_num
, name
);
7112 put_elf_reloc(dynsym
, bss_section
,
7113 offset
, R_386_COPY
, index
);
7114 offset
+= esym
->st_size
;
7115 bss_section
->data_offset
= offset
;
7118 /* STT_NOTYPE or STB_WEAK undefined symbols
7120 /* XXX: STT_NOTYPE is only used to exclude the
7121 unreferenced '_fp_hw' symbol. need a better
7123 if (ELF32_ST_TYPE(sym
->st_info
) == STT_NOTYPE
||
7124 ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
) {
7126 error("undefined symbol '%s'", name
);
7132 /* now look at unresolved dynamic symbols and export
7133 corresponding symbol */
7134 sym_end
= (Elf32_Sym
*)(dynsymtab_section
->data
+
7135 dynsymtab_section
->data_offset
);
7136 for(sym
= (Elf32_Sym
*)dynsymtab_section
->data
+ 1;
7139 if (sym
->st_shndx
== SHN_UNDEF
) {
7140 name
= dynsymtab_section
->link
->data
+ sym
->st_name
;
7141 sym_index
= find_elf_sym(symtab_section
, name
);
7144 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
) {
7145 /* weak symbols can stay undefined */
7147 warning("undefined dynamic symbol '%s'", name
);
7153 build_got_entries();
7155 /* update PLT/GOT sizes so that we can allocate their space */
7156 plt
->data_offset
+= 16 * (nb_plt_entries
+ 1);
7158 /* add a list of needed dlls */
7159 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7160 DLLReference
*dllref
= loaded_dlls
[i
];
7161 if (dllref
->level
== 0)
7162 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
7165 /* add necessary space for other entries */
7166 saved_dynamic_data_offset
= dynamic
->data_offset
;
7167 dynamic
->data_offset
+= 8 * 9;
7169 /* still need to build got entries in case of static link */
7170 build_got_entries();
7174 memset(&ehdr
, 0, sizeof(ehdr
));
7176 /* we add a section for symbols */
7177 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
7178 put_elf_str(strsec
, "");
7180 /* compute number of sections */
7181 shnum
= nb_sections
;
7183 /* this array is used to reorder sections in the output file */
7184 section_order
= malloc(sizeof(int) * shnum
);
7186 error("memory full");
7187 section_order
[0] = 0;
7190 /* compute number of program headers */
7193 case TCC_OUTPUT_OBJ
:
7196 case TCC_OUTPUT_EXE
:
7202 case TCC_OUTPUT_DLL
:
7207 /* allocate strings for section names */
7208 for(i
= 1; i
< nb_sections
; i
++) {
7210 s
->sh_name
= put_elf_str(strsec
, s
->name
);
7211 s
->sh_size
= s
->data_offset
;
7214 /* allocate program segment headers */
7215 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
7217 error("memory full");
7218 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
7220 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7222 /* compute section to program header mapping */
7223 if (file_type
== TCC_OUTPUT_DLL
)
7226 addr
= ELF_START_ADDR
;
7228 /* dynamic relocation table information, for .dynamic section */
7232 /* compute address after headers */
7233 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
7235 /* leave one program header for the program interpreter */
7240 for(j
= 0; j
< 2; j
++) {
7241 ph
->p_type
= PT_LOAD
;
7243 ph
->p_flags
= PF_R
| PF_X
;
7245 ph
->p_flags
= PF_R
| PF_W
;
7246 ph
->p_align
= ELF_PAGE_SIZE
;
7248 /* we do the following ordering: interp, symbol tables,
7249 relocations, progbits, nobits */
7250 /* XXX: do faster and simpler sorting */
7251 for(k
= 0; k
< 5; k
++) {
7252 for(i
= 1; i
< nb_sections
; i
++) {
7254 /* compute if section should be included */
7256 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7260 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7261 (SHF_ALLOC
| SHF_WRITE
))
7267 } else if (s
->sh_type
== SHT_DYNSYM
||
7268 s
->sh_type
== SHT_STRTAB
||
7269 s
->sh_type
== SHT_HASH
) {
7272 } else if (s
->sh_type
== SHT_REL
) {
7275 } else if (s
->sh_type
== SHT_NOBITS
) {
7282 section_order
[sh_order_index
++] = i
;
7284 /* section matches: we align it and add its size */
7286 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7287 ~(s
->sh_addralign
- 1);
7288 s
->sh_offset
= file_offset
;
7289 addr
+= file_offset
- tmp
;
7292 /* update program header infos */
7293 if (ph
->p_offset
== 0) {
7294 ph
->p_offset
= file_offset
;
7296 ph
->p_paddr
= ph
->p_vaddr
;
7298 /* update dynamic relocation infos */
7299 if (s
->sh_type
== SHT_REL
) {
7302 rel_size
+= s
->sh_size
;
7305 if (s
->sh_type
!= SHT_NOBITS
)
7306 file_offset
+= s
->sh_size
;
7309 ph
->p_filesz
= file_offset
- ph
->p_offset
;
7310 ph
->p_memsz
= addr
- ph
->p_vaddr
;
7314 /* if interpreter, then add corresponing program header */
7318 ph
->p_type
= PT_INTERP
;
7319 ph
->p_offset
= interp
->sh_offset
;
7320 ph
->p_vaddr
= interp
->sh_addr
;
7321 ph
->p_paddr
= ph
->p_vaddr
;
7322 ph
->p_filesz
= interp
->sh_size
;
7323 ph
->p_memsz
= interp
->sh_size
;
7325 ph
->p_align
= interp
->sh_addralign
;
7328 /* if dynamic section, then add corresponing program header */
7334 ph
= &phdr
[phnum
- 1];
7336 ph
->p_type
= PT_DYNAMIC
;
7337 ph
->p_offset
= dynamic
->sh_offset
;
7338 ph
->p_vaddr
= dynamic
->sh_addr
;
7339 ph
->p_paddr
= ph
->p_vaddr
;
7340 ph
->p_filesz
= dynamic
->sh_size
;
7341 ph
->p_memsz
= dynamic
->sh_size
;
7342 ph
->p_flags
= PF_R
| PF_W
;
7343 ph
->p_align
= dynamic
->sh_addralign
;
7345 /* put GOT dynamic section address */
7346 put32(got
->data
, dynamic
->sh_addr
);
7348 /* compute the PLT */
7349 plt
->data_offset
= 0;
7351 /* first plt entry */
7352 p
= section_ptr_add(plt
, 16);
7353 p
[0] = 0xff; /* pushl got + 4 */
7355 put32(p
+ 2, got
->sh_addr
+ 4);
7356 p
[6] = 0xff; /* jmp *(got + 8) */
7358 put32(p
+ 8, got
->sh_addr
+ 8);
7360 /* relocation symbols in .dynsym and build PLT. */
7362 sym_end
= (Elf32_Sym
*)(dynsym
->data
+ dynsym
->data_offset
);
7363 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
7366 type
= ELF32_ST_TYPE(sym
->st_info
);
7367 if (sym
->st_shndx
== SHN_UNDEF
) {
7368 if (type
== STT_FUNC
) {
7369 /* one more entry in PLT */
7370 p
= section_ptr_add(plt
, 16);
7371 p
[0] = 0xff; /* jmp *(got + x) */
7373 put32(p
+ 2, got
->sh_addr
+ sym
->st_value
);
7374 p
[6] = 0x68; /* push $xxx */
7375 put32(p
+ 7, plt_offset
);
7376 p
[11] = 0xe9; /* jmp plt_start */
7377 put32(p
+ 12, -(plt
->data_offset
));
7379 /* patch symbol value to point to plt */
7380 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
7384 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
7385 /* do symbol relocation */
7386 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
7389 /* put dynamic section entries */
7391 dynamic
->data_offset
= saved_dynamic_data_offset
;
7392 put_dt(dynamic
, DT_HASH
, hash
->sh_addr
);
7393 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
7394 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
7395 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
7396 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
7397 put_dt(dynamic
, DT_REL
, rel_addr
);
7398 put_dt(dynamic
, DT_RELSZ
, rel_size
);
7399 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
7400 put_dt(dynamic
, DT_NULL
, 0);
7403 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
7404 ehdr
.e_phnum
= phnum
;
7405 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
7408 /* all other sections come after */
7409 for(i
= 1; i
< nb_sections
; i
++) {
7411 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
7413 section_order
[sh_order_index
++] = i
;
7415 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7416 ~(s
->sh_addralign
- 1);
7417 s
->sh_offset
= file_offset
;
7418 if (s
->sh_type
!= SHT_NOBITS
)
7419 file_offset
+= s
->sh_size
;
7422 /* if building executable or DLL, then relocate each section
7423 except the GOT which is already relocated */
7424 if (file_type
!= TCC_OUTPUT_OBJ
) {
7427 /* relocate sections */
7428 /* XXX: ignore sections with allocated relocations ? */
7429 for(i
= 1; i
< nb_sections
; i
++) {
7431 if (s
->reloc
&& s
!= got
)
7432 relocate_section(s
);
7435 /* relocate relocation entries if the relocation tables are
7436 allocated in the executable */
7437 for(i
= 1; i
< nb_sections
; i
++) {
7439 if ((s
->sh_flags
& SHF_ALLOC
) &&
7440 s
->sh_type
== SHT_REL
) {
7445 /* get entry point address */
7446 ehdr
.e_entry
= get_elf_sym_val("_start");
7449 sort_syms(symtab_section
);
7452 file_offset
= (file_offset
+ 3) & -4;
7455 ehdr
.e_ident
[0] = ELFMAG0
;
7456 ehdr
.e_ident
[1] = ELFMAG1
;
7457 ehdr
.e_ident
[2] = ELFMAG2
;
7458 ehdr
.e_ident
[3] = ELFMAG3
;
7459 ehdr
.e_ident
[4] = ELFCLASS32
;
7460 ehdr
.e_ident
[5] = ELFDATA2LSB
;
7461 ehdr
.e_ident
[6] = EV_CURRENT
;
7464 case TCC_OUTPUT_EXE
:
7465 ehdr
.e_type
= ET_EXEC
;
7467 case TCC_OUTPUT_DLL
:
7468 ehdr
.e_type
= ET_DYN
;
7470 case TCC_OUTPUT_OBJ
:
7471 ehdr
.e_type
= ET_REL
;
7474 ehdr
.e_machine
= EM_386
;
7475 ehdr
.e_version
= EV_CURRENT
;
7476 ehdr
.e_shoff
= file_offset
;
7477 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
7478 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
7479 ehdr
.e_shnum
= shnum
;
7480 ehdr
.e_shstrndx
= shnum
- 1;
7482 /* write elf file */
7483 if (file_type
== TCC_OUTPUT_OBJ
)
7487 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
7489 error("could not write '%s'", filename
);
7491 f
= fdopen(fd
, "w");
7492 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
7493 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
7494 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7495 for(i
=1;i
<nb_sections
;i
++) {
7496 s
= sections
[section_order
[i
]];
7497 if (s
->sh_type
!= SHT_NOBITS
) {
7498 while (offset
< s
->sh_offset
) {
7502 size
= s
->data_offset
;
7503 fwrite(s
->data
, 1, size
, f
);
7507 while (offset
< ehdr
.e_shoff
) {
7512 /* output section headers */
7513 for(i
=0;i
<nb_sections
;i
++) {
7515 memset(sh
, 0, sizeof(Elf32_Shdr
));
7518 sh
->sh_name
= s
->sh_name
;
7519 sh
->sh_type
= s
->sh_type
;
7520 sh
->sh_flags
= s
->sh_flags
;
7521 sh
->sh_entsize
= s
->sh_entsize
;
7522 sh
->sh_info
= s
->sh_info
;
7524 sh
->sh_link
= s
->link
->sh_num
;
7525 sh
->sh_addralign
= s
->sh_addralign
;
7526 sh
->sh_addr
= s
->sh_addr
;
7527 sh
->sh_offset
= s
->sh_offset
;
7528 sh
->sh_size
= s
->sh_size
;
7530 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
7534 free(section_order
);
7539 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
7543 data
= malloc(size
);
7545 error("memory full");
7546 lseek(fd
, file_offset
, SEEK_SET
);
7547 read(fd
, data
, size
);
7551 typedef struct SectionMergeInfo
{
7552 Section
*s
; /* corresponding existing section */
7553 unsigned long offset
; /* offset of the new section in the existing section */
7554 int new_section
; /* true if section 's' was added */
7557 /* load an object file and merge it with current files */
7558 /* XXX: handle correctly stab (debug) info */
7559 static int tcc_load_object_file(TCCState
*s1
,
7560 int fd
, unsigned long file_offset
)
7563 Elf32_Shdr
*shdr
, *sh
;
7564 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
;
7565 unsigned char *strsec
, *strtab
;
7566 int *old_to_new_syms
;
7567 char *sh_name
, *name
;
7568 SectionMergeInfo
*sm_table
, *sm
;
7569 Elf32_Sym
*sym
, *symtab
;
7570 Elf32_Rel
*rel
, *rel_end
;
7573 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
7575 if (ehdr
.e_ident
[0] != ELFMAG0
||
7576 ehdr
.e_ident
[1] != ELFMAG1
||
7577 ehdr
.e_ident
[2] != ELFMAG2
||
7578 ehdr
.e_ident
[3] != ELFMAG3
)
7580 /* test if object file */
7581 if (ehdr
.e_type
!= ET_REL
)
7583 /* test CPU specific stuff */
7584 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7585 ehdr
.e_machine
!= EM_386
) {
7587 error("invalid object file");
7590 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
7591 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7592 sm_table
= malloc(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7594 error("memory full");
7595 memset(sm_table
, 0, sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7597 /* load section names */
7598 sh
= &shdr
[ehdr
.e_shstrndx
];
7599 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7601 /* load symtab and strtab */
7605 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7607 if (sh
->sh_type
== SHT_SYMTAB
) {
7609 error("object must contain only one symtab");
7610 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7611 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7612 sm_table
[i
].s
= symtab_section
;
7614 /* now load strtab */
7615 sh
= &shdr
[sh
->sh_link
];
7616 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7620 /* now examine each section and try to merge its content with the
7622 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7623 /* no need to examine section name strtab */
7624 if (i
== ehdr
.e_shstrndx
)
7627 sh_name
= strsec
+ sh
->sh_name
;
7628 /* ignore sections types we do not handle */
7629 if (sh
->sh_type
!= SHT_PROGBITS
&&
7630 sh
->sh_type
!= SHT_REL
&&
7631 sh
->sh_type
!= SHT_NOBITS
)
7633 if (sh
->sh_addralign
< 1)
7634 sh
->sh_addralign
= 1;
7635 /* find corresponding section, if any */
7636 for(j
= 1; j
< nb_sections
;j
++) {
7638 if (!strcmp(s
->name
, sh_name
))
7641 /* not found: create new section */
7642 s
= new_section(sh_name
, sh
->sh_type
, sh
->sh_flags
);
7643 /* take as much info as possible from the section. sh_link and
7644 sh_info will be updated later */
7645 s
->sh_addralign
= sh
->sh_addralign
;
7646 s
->sh_entsize
= sh
->sh_entsize
;
7647 sm_table
[i
].new_section
= 1;
7649 if (sh
->sh_type
!= s
->sh_type
)
7652 /* align start of section */
7653 offset
= s
->data_offset
;
7654 size
= sh
->sh_addralign
- 1;
7655 offset
= (offset
+ size
) & ~size
;
7656 if (sh
->sh_addralign
> s
->sh_addralign
)
7657 s
->sh_addralign
= sh
->sh_addralign
;
7658 s
->data_offset
= offset
;
7659 sm_table
[i
].offset
= offset
;
7661 /* concatenate sections */
7663 if (sh
->sh_type
!= SHT_NOBITS
) {
7665 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
7666 ptr
= section_ptr(s
, size
);
7667 read(fd
, ptr
, size
);
7669 s
->data_offset
+= size
;
7672 /* second short pass to update sh_link and sh_info fields of new
7675 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7677 if (!s
|| !sm_table
[i
].new_section
)
7680 if (sh
->sh_link
> 0)
7681 s
->link
= sm_table
[sh
->sh_link
].s
;
7682 if (sh
->sh_type
== SHT_REL
) {
7683 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
7684 /* update backward link */
7685 sections
[s
->sh_info
]->reloc
= s
;
7689 /* resolve symbols */
7690 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
7691 if (!old_to_new_syms
)
7692 error("memory full");
7693 memset(old_to_new_syms
, 0, nb_syms
* sizeof(int));
7695 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
7696 if (sym
->st_shndx
!= SHN_UNDEF
&&
7697 sym
->st_shndx
< SHN_LORESERVE
) {
7698 sm
= &sm_table
[sym
->st_shndx
];
7699 /* if no corresponding section added, no need to add symbol */
7702 /* convert section number */
7703 sym
->st_shndx
= sm
->s
->sh_num
;
7705 sym
->st_value
+= sm
->offset
;
7708 name
= strtab
+ sym
->st_name
;
7709 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
7710 sym
->st_info
, sym
->st_shndx
, name
);
7711 old_to_new_syms
[i
] = sym_index
;
7714 /* third pass to patch relocation entries */
7715 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7720 offset
= sm_table
[i
].offset
;
7721 switch(s
->sh_type
) {
7723 /* take relocation offset information */
7724 offseti
= sm_table
[sh
->sh_info
].offset
;
7725 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
7726 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
7731 /* convert symbol index */
7732 type
= ELF32_R_TYPE(rel
->r_info
);
7733 sym_index
= ELF32_R_SYM(rel
->r_info
);
7734 /* NOTE: only one symtab assumed */
7735 if (sym_index
>= nb_syms
)
7737 sym_index
= old_to_new_syms
[sym_index
];
7740 error("Invalid relocation entry");
7742 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
7743 /* offset the relocation offset */
7744 rel
->r_offset
+= offseti
;
7753 free(old_to_new_syms
);
7759 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7761 typedef struct ArchiveHeader
{
7762 char ar_name
[16]; /* name of this member */
7763 char ar_date
[12]; /* file mtime */
7764 char ar_uid
[6]; /* owner uid; printed as decimal */
7765 char ar_gid
[6]; /* owner gid; printed as decimal */
7766 char ar_mode
[8]; /* file mode, printed as octal */
7767 char ar_size
[10]; /* file size, printed as decimal */
7768 char ar_fmag
[2]; /* should contain ARFMAG */
7771 /* load a '.a' file */
7772 static int tcc_load_archive(TCCState
*s1
, int fd
)
7779 unsigned long file_offset
;
7781 /* skip magic which was already checked */
7782 read(fd
, magic
, sizeof(magic
));
7785 len
= read(fd
, &hdr
, sizeof(hdr
));
7788 if (len
!= sizeof(hdr
))
7789 error("invalid archive");
7790 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
7791 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
7792 size
= strtol(ar_size
, NULL
, 0);
7793 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
7794 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
7795 if (ar_name
[i
] != ' ')
7798 ar_name
[i
+ 1] = '\0';
7799 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7800 file_offset
= lseek(fd
, 0, SEEK_CUR
);
7801 if (!strcmp(ar_name
, "/") ||
7802 !strcmp(ar_name
, "//") ||
7803 !strcmp(ar_name
, "__.SYMDEF") ||
7804 !strcmp(ar_name
, "__.SYMDEF/") ||
7805 !strcmp(ar_name
, "ARFILENAMES/")) {
7806 /* skip symbol table or archive names */
7808 tcc_load_object_file(s1
, fd
, file_offset
);
7811 size
= (size
+ 1) & ~1;
7812 lseek(fd
, file_offset
+ size
, SEEK_SET
);
7817 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
7818 is referenced by the user (so it should be added as DT_NEEDED in
7819 the generated ELF file) */
7820 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
7823 Elf32_Shdr
*shdr
, *sh
, *sh1
;
7824 int i
, nb_syms
, nb_dts
, sym_bind
;
7825 Elf32_Sym
*sym
, *dynsym
;
7826 Elf32_Dyn
*dt
, *dynamic
;
7827 unsigned char *dynstr
;
7828 const char *name
, *soname
, *p
;
7829 DLLReference
*dllref
;
7831 read(fd
, &ehdr
, sizeof(ehdr
));
7833 /* test CPU specific stuff */
7834 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7835 ehdr
.e_machine
!= EM_386
)
7836 error("bad architecture");
7839 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7841 /* load dynamic section and dynamic symbols */
7845 dynsym
= NULL
; /* avoid warning */
7846 dynstr
= NULL
; /* avoid warning */
7847 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
7848 switch(sh
->sh_type
) {
7850 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
7851 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
7854 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7855 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
7856 sh1
= &shdr
[sh
->sh_link
];
7857 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
7864 /* compute the real library name */
7866 p
= strrchr(soname
, '/');
7870 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
7871 if (dt
->d_tag
== DT_SONAME
) {
7872 soname
= dynstr
+ dt
->d_un
.d_val
;
7876 /* if the dll is already loaded, do not load it */
7877 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7878 dllref
= loaded_dlls
[i
];
7879 if (!strcmp(soname
, dllref
->name
)) {
7880 /* but update level if needed */
7881 if (level
< dllref
->level
)
7882 dllref
->level
= level
;
7887 // printf("loading dll '%s'\n", soname);
7889 /* add the dll and its level */
7890 dllref
= malloc(sizeof(DLLReference
) + strlen(soname
));
7891 dllref
->level
= level
;
7892 strcpy(dllref
->name
, soname
);
7893 dynarray_add((void ***)&loaded_dlls
, &nb_loaded_dlls
, dllref
);
7895 /* add dynamic symbols in dynsym_section */
7896 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
7897 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
7898 if (sym_bind
== STB_LOCAL
)
7900 name
= dynstr
+ sym
->st_name
;
7901 add_elf_sym(dynsymtab_section
, sym
->st_value
, sym
->st_size
,
7902 sym
->st_info
, sym
->st_shndx
, name
);
7905 /* load all referenced DLLs */
7906 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
7909 name
= dynstr
+ dt
->d_un
.d_val
;
7910 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7911 dllref
= loaded_dlls
[i
];
7912 if (!strcmp(name
, dllref
->name
))
7913 goto already_loaded
;
7915 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0)
7916 error("referenced dll '%s' not found", name
);
7926 /* return -2 if error and CH_EOF if eof */
7927 static void ld_skipspaces(void)
7929 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
7933 static int ld_get_cmd(char *cmd
, int cmd_size
)
7942 if (!((ch
>= 'a' && ch
<= 'z') ||
7943 (ch
>= 'A' && ch
<= 'Z') ||
7944 (ch
>= '0' && ch
<= '9') ||
7945 strchr("/.-_+=$:\\,~?*", ch
)))
7947 if ((q
- cmd
) >= (cmd_size
- 1))
7956 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
7958 static int tcc_load_ldscript(TCCState
*s1
)
7961 char filename
[1024];
7967 ret
= ld_get_cmd(cmd
, sizeof(cmd
));
7972 // printf("cmd='%s'\n", cmd);
7973 if (!strcmp(cmd
, "INPUT") ||
7974 !strcmp(cmd
, "GROUP")) {
7980 ld_get_cmd(filename
, sizeof(filename
));
7981 tcc_add_file(s1
, filename
);
7985 } else if (ch
== ')') {
7988 } else if (ch
== CH_EOF
) {
7989 error("unexpected end of file");
7999 /* print the position in the source file of PC value 'pc' by reading
8000 the stabs debug information */
8001 static void rt_printline(unsigned long wanted_pc
)
8003 Stab_Sym
*sym
, *sym_end
;
8004 char func_name
[128];
8005 unsigned long func_addr
, last_pc
, pc
;
8006 const char *incl_files
[INCLUDE_STACK_SIZE
];
8007 int incl_index
, len
, last_line_num
, i
;
8008 const char *str
, *p
;
8010 func_name
[0] = '\0';
8013 last_pc
= 0xffffffff;
8015 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
8016 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
8017 while (sym
< sym_end
) {
8018 switch(sym
->n_type
) {
8019 /* function start or end */
8021 if (sym
->n_strx
== 0) {
8022 func_name
[0] = '\0';
8025 str
= stabstr_section
->data
+ sym
->n_strx
;
8026 p
= strchr(str
, ':');
8028 pstrcpy(func_name
, sizeof(func_name
), str
);
8031 if (len
> sizeof(func_name
) - 1)
8032 len
= sizeof(func_name
) - 1;
8033 memcpy(func_name
, str
, len
);
8034 func_name
[len
] = '\0';
8036 func_addr
= sym
->n_value
;
8039 /* line number info */
8041 pc
= sym
->n_value
+ func_addr
;
8042 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8045 last_line_num
= sym
->n_desc
;
8049 str
= stabstr_section
->data
+ sym
->n_strx
;
8051 if (incl_index
< INCLUDE_STACK_SIZE
) {
8052 incl_files
[incl_index
++] = str
;
8060 if (sym
->n_strx
== 0) {
8061 incl_index
= 0; /* end of translation unit */
8063 str
= stabstr_section
->data
+ sym
->n_strx
;
8064 /* do not add path */
8066 if (len
> 0 && str
[len
- 1] != '/')
8073 /* did not find line number info: */
8074 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
8077 for(i
= 0; i
< incl_index
- 1; i
++)
8078 fprintf(stderr
, "In file included from %s\n",
8080 if (incl_index
> 0) {
8081 fprintf(stderr
, "%s:%d: ",
8082 incl_files
[incl_index
- 1], last_line_num
);
8084 if (func_name
[0] != '\0') {
8085 fprintf(stderr
, "in function '%s()': ", func_name
);
8089 /* emit a run time error at position 'pc' */
8090 void rt_error(unsigned long pc
, const char *fmt
, ...)
8096 vfprintf(stderr
, fmt
, ap
);
8097 fprintf(stderr
, "\n");
8103 /* signal handler for fatal errors */
8104 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
8106 struct ucontext
*uc
= puc
;
8110 pc
= uc
->uc_mcontext
.gregs
[14];
8112 #error please put the right sigcontext field
8117 switch(siginf
->si_code
) {
8120 rt_error(pc
, "division by zero");
8123 rt_error(pc
, "floating point exception");
8129 rt_error(pc
, "dereferencing invalid pointer");
8132 rt_error(pc
, "illegal instruction");
8135 rt_error(pc
, "abort() called");
8138 rt_error(pc
, "caught signal %d", signum
);
8145 /* launch the compiled program with the given arguments */
8146 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8149 int (*prog_main
)(int, char **);
8150 void (*bound_init
)(void);
8153 tcc_add_runtime(s1
);
8155 relocate_common_syms();
8157 /* compute relocation address : section are relocated in place */
8158 for(i
= 1; i
< nb_sections
; i
++) {
8160 if (s
->sh_flags
& SHF_ALLOC
)
8161 s
->sh_addr
= (unsigned long)s
->data
;
8166 /* relocate each section */
8167 for(i
= 1; i
< nb_sections
; i
++) {
8170 relocate_section(s
);
8173 prog_main
= (void *)get_elf_sym_val("main");
8177 error("debug mode currently not available for Windows");
8179 struct sigaction sigact
;
8180 /* install TCC signal handlers to print debug info on fatal
8182 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8183 sigact
.sa_sigaction
= sig_error
;
8184 sigemptyset(&sigact
.sa_mask
);
8185 sigaction(SIGFPE
, &sigact
, NULL
);
8186 sigaction(SIGILL
, &sigact
, NULL
);
8187 sigaction(SIGSEGV
, &sigact
, NULL
);
8188 sigaction(SIGBUS
, &sigact
, NULL
);
8189 sigaction(SIGABRT
, &sigact
, NULL
);
8193 #ifdef CONFIG_TCC_BCHECK
8194 if (do_bounds_check
) {
8195 /* XXX: use .init section so that it also work in binary ? */
8196 bound_init
= (void *)get_elf_sym_val("__bound_init");
8200 return (*prog_main
)(argc
, argv
);
8203 TCCState
*tcc_new(void)
8208 s
= malloc(sizeof(TCCState
));
8211 s
->output_type
= TCC_OUTPUT_MEMORY
;
8213 /* default include paths */
8214 tcc_add_include_path(s
, "/usr/include");
8215 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8216 tcc_add_include_path(s
, "/usr/local/include");
8218 /* add all tokens */
8219 tok_ident
= TOK_IDENT
;
8224 tok_alloc(p
, r
- p
- 1);
8228 /* standard defines */
8229 tcc_define_symbol(s
, "__STDC__", NULL
);
8230 #if defined(TCC_TARGET_I386)
8231 tcc_define_symbol(s
, "__i386__", NULL
);
8233 /* tiny C specific defines */
8234 tcc_define_symbol(s
, "__TINYC__", NULL
);
8236 /* default library paths */
8237 tcc_add_library_path(s
, "/usr/local/lib");
8238 tcc_add_library_path(s
, "/usr/lib");
8239 tcc_add_library_path(s
, "/lib");
8241 /* no section zero */
8242 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
8244 /* create standard sections */
8245 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8246 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8247 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8249 /* symbols are always generated for linking stage */
8250 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
8251 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
8252 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
8253 put_elf_str(strtab_section
, "");
8254 symtab_section
->link
= strtab_section
;
8255 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
8256 new_section_hash(".hashtab", SHF_PRIVATE
,
8257 ELF_SYM_HASH_SIZE
, symtab_section
);
8259 /* private symbol table for dynamic symbols */
8260 dynsymtab_section
= new_section(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
);
8261 dynsymtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
8262 dynstrtab_section
= new_section(".dynstrtab", SHT_STRTAB
, SHF_PRIVATE
);
8263 put_elf_str(dynstrtab_section
, "");
8264 dynsymtab_section
->link
= dynstrtab_section
;
8265 put_elf_sym(dynsymtab_section
, 0, 0, 0, 0, 0, NULL
);
8266 new_section_hash(".dynhashtab", SHF_PRIVATE
,
8267 ELF_SYM_HASH_SIZE
, dynsymtab_section
);
8271 void tcc_delete(TCCState
*s
)
8276 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
8280 pathname1
= strdup(pathname
);
8283 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
8287 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
8292 BufferedFile
*saved_file
;
8294 /* find source file type with extension */
8295 ext
= strrchr(filename
, '.');
8301 file
= tcc_open(filename
);
8303 if (flags
& AFF_PRINT_ERROR
) {
8304 error("file '%s' not found", filename
);
8311 if (!ext
|| !strcmp(ext
, "c")) {
8312 /* C file assumed */
8316 /* assume executable format: auto guess file type */
8317 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
8318 error("could not read header");
8319 lseek(fd
, 0, SEEK_SET
);
8321 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8322 ehdr
.e_ident
[1] == ELFMAG1
&&
8323 ehdr
.e_ident
[2] == ELFMAG2
&&
8324 ehdr
.e_ident
[3] == ELFMAG3
) {
8325 file
->line_num
= 0; /* do not display line number if error */
8326 if (ehdr
.e_type
== ET_REL
) {
8327 tcc_load_object_file(s
, fd
, 0);
8328 } else if (ehdr
.e_type
== ET_DYN
) {
8329 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
8331 error("unrecognized ELF file");
8333 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8334 file
->line_num
= 0; /* do not display line number if error */
8335 tcc_load_archive(s
, fd
);
8337 /* as GNU ld, consider it is an ld script if not recognized */
8338 if (tcc_load_ldscript(s
) < 0)
8339 error("unrecognized file type");
8347 void tcc_add_file(TCCState
*s
, const char *filename
)
8349 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8352 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8356 pathname1
= strdup(pathname
);
8359 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
8363 /* find and load a dll. Return non zero if not found */
8364 /* XXX: add '-rpath' option support ? */
8365 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8370 for(i
= 0; i
< nb_library_paths
; i
++) {
8371 snprintf(buf
, sizeof(buf
), "%s/%s",
8372 library_paths
[i
], filename
);
8373 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8379 /* the library name is the same as the argument of the '-l' option */
8380 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8386 /* if we output to memory, then we simply we dlopen(). */
8387 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8388 /* Since the libc is already loaded, we don't need to load it again */
8389 if (!strcmp(libraryname
, "c"))
8391 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8392 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8398 /* first we look for the dynamic library if not static linking */
8400 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8401 if (tcc_add_dll(s
, buf
, 0) == 0)
8405 /* then we look for the static library */
8406 for(i
= 0; i
< nb_library_paths
; i
++) {
8407 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8408 library_paths
[i
], libraryname
);
8409 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8415 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8417 add_elf_sym(symtab_section
, val
, 0,
8418 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8423 int tcc_set_output_type(TCCState
*s
, int output_type
)
8425 s
->output_type
= output_type
;
8427 /* add libc crt1/crti objects */
8428 if (output_type
== TCC_OUTPUT_EXE
||
8429 output_type
== TCC_OUTPUT_DLL
) {
8430 if (output_type
!= TCC_OUTPUT_DLL
)
8431 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8432 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8437 #if !defined(LIBTCC)
8441 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8442 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8443 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
8444 " [--] infile1 [infile2... --] [infile_args...]\n"
8446 "General options:\n"
8447 " -c compile only - generate an object file\n"
8448 " -o outfile set output filename\n"
8449 " -- allows multiples input files if no -o option given. Also\n"
8450 " separate input files from runtime arguments\n"
8451 " -Bdir set tcc internal library path\n"
8452 " -bench output compilation statistics\n"
8453 "Preprocessor options:\n"
8454 " -Idir add include path 'dir'\n"
8455 " -Dsym[=val] define 'sym' with value 'val'\n"
8456 " -Usym undefine 'sym'\n"
8457 "C compiler options:\n"
8458 " -g generate runtime debug info\n"
8459 #ifdef CONFIG_TCC_BCHECK
8460 " -b compile with built-in memory and bounds checker (implies -g)\n"
8463 " -Ldir add library path 'dir'\n"
8464 " -llib link with dynamic library 'lib'\n"
8465 " -shared generate a shared library (NOT WORKING YET)\n"
8466 " -static static linking\n"
8470 int main(int argc
, char **argv
)
8473 int optind
, output_type
, multiple_files
, i
;
8479 output_type
= TCC_OUTPUT_MEMORY
;
8487 if (optind
>= argc
) {
8497 /* '--' enables multiple files input */
8499 } else if (r
[1] == 'h' || r
[1] == '?') {
8501 } else if (r
[1] == 'I') {
8502 if (tcc_add_include_path(s
, r
+ 2) < 0)
8503 error("too many include paths");
8504 } else if (r
[1] == 'D') {
8507 value
= strchr(sym
, '=');
8512 tcc_define_symbol(s
, sym
, value
);
8513 } else if (r
[1] == 'U') {
8514 tcc_undefine_symbol(s
, r
+ 2);
8515 } else if (r
[1] == 'L') {
8516 tcc_add_library_path(s
, r
+ 2);
8517 } else if (r
[1] == 'B') {
8518 /* set tcc utilities path (mainly for tcc development) */
8519 tcc_lib_path
= r
+ 2;
8520 } else if (r
[1] == 'l') {
8521 dynarray_add((void ***)&libraries
, &nb_libraries
, r
+ 2);
8522 } else if (!strcmp(r
+ 1, "bench")) {
8524 #ifdef CONFIG_TCC_BCHECK
8525 } else if (r
[1] == 'b') {
8526 if (!do_bounds_check
) {
8527 do_bounds_check
= 1;
8529 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8530 /* create bounds sections */
8531 bounds_section
= new_section(".bounds",
8532 SHT_PROGBITS
, SHF_ALLOC
);
8533 lbounds_section
= new_section(".lbounds",
8534 SHT_PROGBITS
, SHF_ALLOC
);
8535 /* debug is implied */
8539 } else if (r
[1] == 'g') {
8540 #ifdef CONFIG_TCC_BCHECK
8547 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
8548 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8549 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
8550 put_elf_str(stabstr_section
, "");
8551 stab_section
->link
= stabstr_section
;
8552 /* put first entry */
8553 put_stabs("", 0, 0, 0, 0);
8556 /* the following options are only for testing, so not
8560 output_type
= TCC_OUTPUT_OBJ
;
8561 } else if (!strcmp(r
+ 1, "static")) {
8563 } else if (!strcmp(r
+ 1, "shared")) {
8564 output_type
= TCC_OUTPUT_DLL
;
8565 } else if (r
[1] == 'o') {
8569 outfile
= argv
[optind
++];
8571 error("invalid option -- '%s'", r
);
8575 /* if outfile provided without other options, we output an
8577 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8578 output_type
= TCC_OUTPUT_EXE
;
8580 /* warning if not supported features */
8581 if (output_type
== TCC_OUTPUT_DLL
)
8582 warning("dll output is currently not supported");
8583 #ifdef CONFIG_TCC_BCHECK
8584 if (do_bounds_check
&& output_type
!= TCC_OUTPUT_MEMORY
)
8585 warning("bounds checking is currently only supported for in-memory execution");
8588 tcc_set_output_type(s
, output_type
);
8590 tcc_add_file(s
, argv
[optind
]);
8591 if (multiple_files
) {
8592 while ((optind
+ 1) < argc
) {
8597 error("'--' expected");
8604 /* add specified libraries */
8605 for(i
= 0; i
< nb_libraries
;i
++) {
8606 if (tcc_add_library(s
, libraries
[i
]) < 0)
8607 error("cannot find -l%s", libraries
[i
]);
8611 printf("total: %d idents, %d lines, %d bytes\n",
8612 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
8615 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8616 tcc_output_file(s
, outfile
);
8619 return tcc_run(s
, argc
- optind
, argv
+ optind
);