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 char *data
; /* section data */
139 unsigned char *data_ptr
; /* current data pointer */
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 simply 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
;
230 int nb_sections
; /* number of sections, including first dummy section */
231 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
232 Section
*cur_text_section
; /* current section where function code is
234 /* bound check related sections */
235 Section
*bounds_section
; /* contains global data bound description */
236 Section
*lbounds_section
; /* contains local data bound description */
237 /* symbol sections */
238 Section
*symtab_section
, *strtab_section
;
239 /* temporary dynamic symbol sections (for dll loading) */
240 Section
*dynsymtab_section
, *dynstrtab_section
;
241 /* exported dynamic symbol section */
245 unsigned long *got_offsets
;
250 /* array of all loaded dlls (including those referenced by loaded
252 DLLReference
**loaded_dlls
;
256 Section
*stab_section
, *stabstr_section
;
258 char **library_paths
;
259 int nb_library_paths
;
261 /* loc : local variable index
262 ind : output code index
264 anon_sym: anonymous symbol index
267 prog
, ind
, loc
, const_wanted
;
268 int global_expr
; /* true if compound literals must be allocated
269 globally (used during initializers parsing */
270 int func_vt
, func_vc
; /* current function return type (used by
271 return instruction) */
272 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
274 TokenSym
**table_ident
;
275 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
276 char token_buf
[STRING_MAX_SIZE
+ 1];
278 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
280 SValue vstack
[VSTACK_SIZE
], *vtop
;
281 int *macro_ptr
, *macro_ptr_allocated
;
282 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
283 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
284 char **include_paths
;
285 int nb_include_paths
;
286 int char_pointer_type
;
289 /* compile with debug symbol (and use them if error during execution) */
292 /* compile with built-in memory and bounds checker */
293 int do_bounds_check
= 0;
295 /* display benchmark infos */
300 /* use GNU C extensions */
303 /* use Tiny C extensions */
306 /* if true, static linking is performed */
309 /* give the path of the tcc libraries */
310 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
316 /* The current value can be: */
317 #define VT_VALMASK 0x00ff
318 #define VT_CONST 0x00f0 /* constant in vc
319 (must be first non register value) */
320 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
321 #define VT_LOCAL 0x00f2 /* offset on stack */
322 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
323 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
324 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
325 #define VT_LVAL 0x0100 /* var is an lvalue */
326 #define VT_SYM 0x0200 /* a symbol value is added */
327 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
328 char/short stored in integer registers) */
329 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
330 dereferencing value */
331 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
332 bounding function call point is in vc */
333 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
334 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
335 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
336 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
339 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
341 #define VT_INT 0 /* integer type */
342 #define VT_BYTE 1 /* signed byte type */
343 #define VT_SHORT 2 /* short type */
344 #define VT_VOID 3 /* void type */
345 #define VT_PTR 4 /* pointer */
346 #define VT_ENUM 5 /* enum definition */
347 #define VT_FUNC 6 /* function type */
348 #define VT_STRUCT 7 /* struct/union definition */
349 #define VT_FLOAT 8 /* IEEE float */
350 #define VT_DOUBLE 9 /* IEEE double */
351 #define VT_LDOUBLE 10 /* IEEE long double */
352 #define VT_BOOL 11 /* ISOC99 boolean type */
353 #define VT_LLONG 12 /* 64 bit integer */
354 #define VT_LONG 13 /* long integer (NEVER USED as type, only
356 #define VT_BTYPE 0x000f /* mask for basic type */
357 #define VT_UNSIGNED 0x0010 /* unsigned type */
358 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
359 #define VT_BITFIELD 0x0040 /* bitfield modifier */
362 #define VT_EXTERN 0x00000080 /* extern definition */
363 #define VT_STATIC 0x00000100 /* static variable */
364 #define VT_TYPEDEF 0x00000200 /* typedef definition */
366 /* type mask (except storage) */
367 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
371 /* warning: the following compare tokens depend on i386 asm code */
383 #define TOK_LAND 0xa0
387 #define TOK_MID 0xa3 /* inc/dec, to void constant */
389 #define TOK_UDIV 0xb0 /* unsigned division */
390 #define TOK_UMOD 0xb1 /* unsigned modulo */
391 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
392 #define TOK_CINT 0xb3 /* number in tokc */
393 #define TOK_CCHAR 0xb4 /* char constant in tokc */
394 #define TOK_STR 0xb5 /* pointer to string in tokc */
395 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
396 #define TOK_LCHAR 0xb7
397 #define TOK_LSTR 0xb8
398 #define TOK_CFLOAT 0xb9 /* float constant */
399 #define TOK_LINENUM 0xba /* line number info */
400 #define TOK_CDOUBLE 0xc0 /* double constant */
401 #define TOK_CLDOUBLE 0xc1 /* long double constant */
402 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
403 #define TOK_ADDC1 0xc3 /* add with carry generation */
404 #define TOK_ADDC2 0xc4 /* add with carry use */
405 #define TOK_SUBC1 0xc5 /* add with carry generation */
406 #define TOK_SUBC2 0xc6 /* add with carry use */
407 #define TOK_CUINT 0xc8 /* unsigned int constant */
408 #define TOK_CLLONG 0xc9 /* long long constant */
409 #define TOK_CULLONG 0xca /* unsigned long long constant */
410 #define TOK_ARROW 0xcb
411 #define TOK_DOTS 0xcc /* three dots */
412 #define TOK_SHR 0xcd /* unsigned shift right */
414 #define TOK_SHL 0x01 /* shift left */
415 #define TOK_SAR 0x02 /* signed shift right */
417 /* assignement operators : normal operator or 0x80 */
418 #define TOK_A_MOD 0xa5
419 #define TOK_A_AND 0xa6
420 #define TOK_A_MUL 0xaa
421 #define TOK_A_ADD 0xab
422 #define TOK_A_SUB 0xad
423 #define TOK_A_DIV 0xaf
424 #define TOK_A_XOR 0xde
425 #define TOK_A_OR 0xfc
426 #define TOK_A_SHL 0x81
427 #define TOK_A_SAR 0x82
429 #define TOK_EOF (-1) /* end of file */
431 /* all identificators and strings have token above that */
432 #define TOK_IDENT 256
453 /* ignored types Must have contiguous values */
459 TOK___SIGNED__
, /* gcc keyword */
462 TOK___INLINE__
, /* gcc keyword */
465 /* unsupported type */
479 /* preprocessor only */
480 TOK_UIDENT
, /* first "user" ident (not keyword) */
481 TOK_DEFINE
= TOK_UIDENT
,
497 /* special identifiers */
500 #define DEF(id, str) id,
506 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
507 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
508 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
509 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
510 "sizeof\0__attribute__\0"
511 /* the following are not keywords. They are included to ease parsing */
512 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
513 "defined\0undef\0error\0line\0"
514 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
516 /* builtin functions */
517 #define DEF(id, str) str "\0"
523 #define snprintf _snprintf
526 #if defined(WIN32) || defined(TCC_UCLIBC)
527 /* currently incorrect */
528 long double strtold(const char *nptr
, char **endptr
)
530 return (long double)strtod(nptr
, endptr
);
532 float strtof(const char *nptr
, char **endptr
)
534 return (float)strtod(nptr
, endptr
);
537 /* XXX: need to define this to use them in non ISOC99 context */
538 extern float strtof (const char *__nptr
, char **__endptr
);
539 extern long double strtold (const char *__nptr
, char **__endptr
);
542 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
543 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
547 void next_nomacro(void);
548 int expr_const(void);
552 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
553 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
556 void gv2(int rc1
, int rc2
);
557 void move_reg(int r
, int s
);
558 void save_regs(int n
);
559 void save_reg(int r
);
565 void macro_subst(TokenString
*tok_str
,
566 Sym
**nested_list
, int *macro_str
);
567 int save_reg_forced(int r
);
569 void force_charshort_cast(int t
);
570 void gen_cast(int t
);
572 Sym
*sym_find(int v
);
573 Sym
*sym_push(int v
, int t
, int r
, int c
);
576 int type_size(int t
, int *a
);
577 int pointed_type(int t
);
578 int pointed_size(int t
);
579 int is_compatible_types(int t1
, int t2
);
580 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
581 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
583 void error(const char *fmt
, ...);
584 void rt_error(unsigned long pc
, const char *fmt
, ...);
586 void vset(int t
, int r
, int v
);
587 void type_to_str(char *buf
, int buf_size
,
588 int t
, const char *varstr
);
589 char *get_tok_str(int v
, CValue
*cv
);
590 Sym
*external_sym(int v
, int u
, int r
);
591 static Sym
*get_sym_ref(int t
, Section
*sec
,
592 unsigned long offset
, unsigned long size
);
594 /* section generation */
595 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
);
596 void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
597 static int put_elf_str(Section
*s
, const char *sym
);
598 static int put_elf_sym(Section
*s
,
599 unsigned long value
, unsigned long size
,
600 int info
, int other
, int shndx
, const char *name
);
601 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
602 int type
, int symbol
);
603 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
604 static void put_stabn(int type
, int other
, int desc
, int value
);
605 static void put_stabd(int type
, int other
, int desc
);
606 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
608 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
609 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
610 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
612 /* true if float/double/long double type */
613 static inline int is_float(int t
)
617 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
620 #ifdef TCC_TARGET_I386
621 #include "i386-gen.c"
627 #ifdef CONFIG_TCC_STATIC
629 #define RTLD_LAZY 0x001
630 #define RTLD_NOW 0x002
631 #define RTLD_GLOBAL 0x100
633 /* dummy function for profiling */
634 void *dlopen(const char *filename
, int flag
)
639 const char *dlerror(void)
644 typedef struct TCCSyms
{
649 #define TCCSYM(a) { #a, &a, },
651 /* add the symbol you want here if no dynamic linking is done */
652 static TCCSyms tcc_syms
[] = {
660 void *dlsym(void *handle
, const char *symbol
)
664 while (p
->str
!= NULL
) {
665 if (!strcmp(p
->str
, symbol
))
674 /********************************************************/
676 /* we use our own 'finite' function to avoid potential problems with
677 non standard math libs */
678 /* XXX: endianness dependant */
679 int ieee_finite(double d
)
682 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
685 /* copy a string and truncate it. */
686 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
693 q_end
= buf
+ buf_size
- 1;
705 /* strcat and truncate. */
706 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
711 pstrcpy(buf
+ len
, buf_size
- len
, s
);
715 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
722 /* every power of two we double array size */
723 if ((nb
& (nb
- 1)) == 0) {
728 pp
= realloc(pp
, nb_alloc
* sizeof(void *));
730 error("memory full");
737 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
742 sec
= malloc(sizeof(Section
));
744 error("memory full");
745 memset(sec
, 0, sizeof(Section
));
746 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
747 sec
->sh_type
= sh_type
;
748 sec
->sh_flags
= sh_flags
;
755 sec
->sh_addralign
= 4;
758 sec
->sh_addralign
= 1;
761 sec
->sh_addralign
= 32; /* default conservative alignment */
765 /* XXX: currently, a single malloc */
766 data
= malloc(SECTION_VSIZE
);
768 error("could not alloc section '%s'", name
);
770 data
= mmap(NULL
, SECTION_VSIZE
,
771 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
772 MAP_PRIVATE
| MAP_ANONYMOUS
,
774 if (data
== (void *)(-1))
775 error("could not mmap section '%s'", name
);
778 sec
->data_ptr
= data
;
780 /* only add section if not private */
781 if (!(sh_flags
& SHF_PRIVATE
)) {
782 sec
->sh_num
= nb_sections
;
783 dynarray_add((void ***)§ions
, &nb_sections
, sec
);
788 /* return a reference to a section, and create it if it does not
790 Section
*find_section(const char *name
)
794 for(i
= 1; i
< nb_sections
; i
++) {
796 if (!strcmp(name
, sec
->name
))
799 /* sections are created as PROGBITS */
800 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
803 /* add a new relocation entry to symbol 'sym' in section 's' */
804 void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
807 put_extern_sym(sym
, NULL
, 0);
808 /* now we can add ELF relocation info */
809 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
812 static inline int isid(int c
)
814 return (c
>= 'a' && c
<= 'z') ||
815 (c
>= 'A' && c
<= 'Z') ||
819 static inline int isnum(int c
)
821 return c
>= '0' && c
<= '9';
824 static inline int toup(int c
)
826 if (ch
>= 'a' && ch
<= 'z')
827 return ch
- 'a' + 'A';
837 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
838 fprintf(stderr
, "In file included from %s:%d:\n",
839 (*f
)->filename
, (*f
)->line_num
);
840 if (file
->line_num
> 0) {
841 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
843 fprintf(stderr
, "%s: ", file
->filename
);
846 fprintf(stderr
, "tcc: ");
850 void error(const char *fmt
, ...)
855 vfprintf(stderr
, fmt
, ap
);
856 fprintf(stderr
, "\n");
861 void expect(const char *msg
)
863 error("%s expected", msg
);
866 void warning(const char *fmt
, ...)
872 fprintf(stderr
, "warning: ");
873 vfprintf(stderr
, fmt
, ap
);
874 fprintf(stderr
, "\n");
881 error("'%c' expected", c
);
885 void test_lvalue(void)
887 if (!(vtop
->r
& VT_LVAL
))
891 TokenSym
*tok_alloc(const char *str
, int len
)
893 TokenSym
*ts
, **pts
, **ptable
;
900 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
902 pts
= &hash_ident
[h
];
907 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
909 pts
= &(ts
->hash_next
);
912 if (tok_ident
>= SYM_FIRST_ANOM
)
913 error("memory full");
915 /* expand token table if needed */
916 i
= tok_ident
- TOK_IDENT
;
917 if ((i
% TOK_ALLOC_INCR
) == 0) {
918 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
920 error("memory full");
921 table_ident
= ptable
;
924 ts
= malloc(sizeof(TokenSym
) + len
);
926 error("memory full");
928 ts
->tok
= tok_ident
++;
930 ts
->hash_next
= NULL
;
931 memcpy(ts
->str
, str
, len
+ 1);
936 void add_char(char **pp
, int c
)
940 if (c
== '\'' || c
== '\"' || c
== '\\') {
941 /* XXX: could be more precise if char or string */
944 if (c
>= 32 && c
<= 126) {
951 *p
++ = '0' + ((c
>> 6) & 7);
952 *p
++ = '0' + ((c
>> 3) & 7);
953 *p
++ = '0' + (c
& 7);
959 /* XXX: buffer overflow */
960 char *get_tok_str(int v
, CValue
*cv
)
962 static char buf
[STRING_MAX_SIZE
+ 1];
967 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
968 sprintf(buf
, "%u", cv
->ui
);
970 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
977 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
981 for(i
=0;i
<ts
->len
;i
++)
982 add_char(&p
, ts
->str
[i
]);
986 } else if (v
< TOK_IDENT
) {
991 } else if (v
< tok_ident
) {
992 return table_ident
[v
- TOK_IDENT
]->str
;
993 } else if (v
>= SYM_FIRST_ANOM
) {
994 /* special name for anonymous symbol */
995 sprintf(buf
, "L.%u", v
- SYM_FIRST_ANOM
);
998 /* should never happen */
1003 /* push, without hashing */
1004 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1007 s
= malloc(sizeof(Sym
));
1009 error("memory full");
1020 /* find a symbol and return its associated structure. 's' is the top
1021 of the symbol stack */
1022 Sym
*sym_find2(Sym
*s
, int v
)
1032 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1034 /* find a symbol and return its associated structure. 'st' is the
1036 Sym
*sym_find1(SymStack
*st
, int v
)
1040 s
= st
->hash
[HASH_SYM(v
)];
1049 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1052 s
= sym_push2(&st
->top
, v
, t
, c
);
1053 /* add in hash table */
1055 ps
= &st
->hash
[HASH_SYM(v
)];
1062 /* find a symbol in the right symbol space */
1063 Sym
*sym_find(int v
)
1066 s
= sym_find1(&local_stack
, v
);
1068 s
= sym_find1(&global_stack
, v
);
1072 /* push a given symbol on the symbol stack */
1073 Sym
*sym_push(int v
, int t
, int r
, int c
)
1076 if (local_stack
.top
)
1077 s
= sym_push1(&local_stack
, v
, t
, c
);
1079 s
= sym_push1(&global_stack
, v
, t
, c
);
1084 /* pop symbols until top reaches 'b' */
1085 void sym_pop(SymStack
*st
, Sym
*b
)
1092 /* free hash table entry, except if symbol was freed (only
1093 used for #undef symbols) */
1095 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1102 /* undefined a hashed symbol (used for #undef). Its name is set to
1104 void sym_undef(SymStack
*st
, Sym
*s
)
1107 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1108 while (*ss
!= NULL
) {
1111 ss
= &(*ss
)->hash_next
;
1119 BufferedFile
*tcc_open(const char *filename
)
1124 fd
= open(filename
, O_RDONLY
);
1127 bf
= malloc(sizeof(BufferedFile
));
1133 bf
->buf_ptr
= bf
->buffer
;
1134 bf
->buf_end
= bf
->buffer
;
1135 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1136 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1138 // printf("opening '%s'\n", filename);
1142 void tcc_close(BufferedFile
*bf
)
1144 total_lines
+= bf
->line_num
;
1149 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1150 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1152 /* fill input buffer and return next char */
1153 int tcc_getc_slow(BufferedFile
*bf
)
1156 /* only tries to read if really end of buffer */
1157 if (bf
->buf_ptr
>= bf
->buf_end
) {
1159 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1166 bf
->buf_ptr
= bf
->buffer
;
1167 bf
->buf_end
= bf
->buffer
+ len
;
1168 *bf
->buf_end
= CH_EOB
;
1170 if (bf
->buf_ptr
< bf
->buf_end
) {
1171 return *bf
->buf_ptr
++;
1173 bf
->buf_ptr
= bf
->buf_end
;
1178 /* no need to put that inline */
1179 void handle_eob(void)
1182 ch1
= tcc_getc_slow(file
);
1186 if (include_stack_ptr
== include_stack
)
1188 /* add end of include file debug info */
1190 put_stabd(N_EINCL
, 0, 0);
1192 /* pop include stack */
1194 include_stack_ptr
--;
1195 file
= *include_stack_ptr
;
1199 /* read next char from current input file */
1200 static inline void inp(void)
1202 ch1
= TCC_GETC(file
);
1203 /* end of buffer/file handling */
1208 // printf("ch1=%c 0x%x\n", ch1, ch1);
1211 /* input with '\\n' handling */
1212 static inline void minp(void)
1217 if (ch
== '\\' && ch1
== '\n') {
1221 //printf("ch=%c 0x%x\n", ch, ch);
1225 /* same as minp, but also skip comments */
1233 /* single line C++ comments */
1235 while (ch1
!= '\n' && ch1
!= -1)
1238 ch
= ' '; /* return space */
1239 } else if (ch1
== '*') {
1245 if (c
== '*' && ch1
== '/') {
1247 ch
= ' '; /* return space */
1259 void skip_spaces(void)
1261 while (ch
== ' ' || ch
== '\t')
1265 /* skip block of text until #else, #elif or #endif. skip also pairs of
1267 void preprocess_skip(void)
1272 while (ch
!= '\n') {
1283 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1285 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1287 else if (tok
== TOK_ENDIF
)
1293 /* ParseState handling */
1295 /* XXX: currently, no include file info is stored. Thus, we cannot display
1296 accurate messages if the function or data definition spans multiple
1299 /* save current parse state in 's' */
1300 void save_parse_state(ParseState
*s
)
1302 s
->line_num
= file
->line_num
;
1303 s
->macro_ptr
= macro_ptr
;
1308 /* restore parse state from 's' */
1309 void restore_parse_state(ParseState
*s
)
1311 file
->line_num
= s
->line_num
;
1312 macro_ptr
= s
->macro_ptr
;
1317 /* return the number of additionnal 'ints' necessary to store the
1319 static inline int tok_ext_size(int t
)
1337 return LDOUBLE_SIZE
/ 4;
1343 /* token string handling */
1345 static inline void tok_str_new(TokenString
*s
)
1349 s
->last_line_num
= -1;
1352 static void tok_str_add(TokenString
*s
, int t
)
1358 if ((len
& 63) == 0) {
1359 str
= realloc(str
, (len
+ 64) * sizeof(int));
1368 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1372 n
= tok_ext_size(t
);
1374 tok_str_add(s
, cv
->tab
[i
]);
1377 /* add the current parse token in token string 's' */
1378 static void tok_str_add_tok(TokenString
*s
)
1382 /* save line number info */
1383 if (file
->line_num
!= s
->last_line_num
) {
1384 s
->last_line_num
= file
->line_num
;
1385 cval
.i
= s
->last_line_num
;
1386 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1388 tok_str_add2(s
, tok
, &tokc
);
1391 /* get a token from an integer array and increment pointer accordingly */
1392 static int tok_get(int **tok_str
, CValue
*cv
)
1398 n
= tok_ext_size(t
);
1405 /* eval an expression for #if/#elif */
1406 int expr_preprocess(void)
1416 next(); /* do macro subst */
1417 if (tok
== TOK_DEFINED
) {
1422 c
= sym_find1(&define_stack
, tok
) != 0;
1427 } else if (tok
>= TOK_IDENT
) {
1428 /* if undefined macro */
1432 tok_str_add_tok(&str
);
1434 tok_str_add(&str
, -1); /* simulate end of file */
1435 tok_str_add(&str
, 0);
1436 /* now evaluate C constant expression */
1437 macro_ptr
= str
.str
;
1445 #if defined(DEBUG) || defined(PP_DEBUG)
1446 void tok_print(int *str
)
1452 t
= tok_get(&str
, &cval
);
1455 printf(" %s", get_tok_str(t
, &cval
));
1461 /* parse after #define */
1462 void parse_define(void)
1464 Sym
*s
, *first
, **ps
;
1465 int v
, t
, varg
, is_vaargs
;
1469 /* XXX: should check if same macro (ANSI) */
1472 /* '(' must be just after macro definition for MACRO_FUNC */
1477 while (tok
!= ')') {
1481 if (varg
== TOK_DOTS
) {
1482 varg
= TOK___VA_ARGS__
;
1484 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1488 if (varg
< TOK_IDENT
)
1489 error("badly punctuated parameter list");
1490 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1502 if (ch
== '\n' || ch
== -1)
1505 tok_str_add2(&str
, tok
, &tokc
);
1507 tok_str_add(&str
, 0);
1509 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1512 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1516 void preprocess(void)
1519 char buf
[1024], *q
, *p
;
1527 if (tok
== TOK_DEFINE
) {
1530 } else if (tok
== TOK_UNDEF
) {
1532 s
= sym_find1(&define_stack
, tok
);
1533 /* undefine symbol by putting an invalid name */
1535 sym_undef(&define_stack
, s
);
1536 } else if (tok
== TOK_INCLUDE
) {
1541 } else if (ch
== '\"') {
1546 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1547 if ((q
- buf
) < sizeof(buf
) - 1)
1555 error("#include syntax error");
1556 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1559 /* eat all spaces and comments after include */
1560 /* XXX: slightly incorrect */
1561 while (ch1
!= '\n' && ch1
!= -1)
1564 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1565 error("memory full");
1567 /* first search in current dir if "header.h" */
1569 p
= strrchr(file
->filename
, '/');
1571 size
= p
+ 1 - file
->filename
;
1572 if (size
> sizeof(buf1
) - 1)
1573 size
= sizeof(buf1
) - 1;
1574 memcpy(buf1
, file
->filename
, size
);
1576 pstrcat(buf1
, sizeof(buf1
), buf
);
1581 /* now search in standard include path */
1582 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1583 strcpy(buf1
, include_paths
[i
]);
1590 error("include file '%s' not found", buf
);
1593 /* push current file in stack */
1594 /* XXX: fix current line init */
1595 *include_stack_ptr
++ = file
;
1597 /* add include file debug info */
1599 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1601 } else if (tok
== TOK_IFNDEF
) {
1604 } else if (tok
== TOK_IF
) {
1605 c
= expr_preprocess();
1607 } else if (tok
== TOK_IFDEF
) {
1611 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1613 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1614 error("memory full");
1615 *ifdef_stack_ptr
++ = c
;
1617 } else if (tok
== TOK_ELSE
) {
1618 if (ifdef_stack_ptr
== ifdef_stack
)
1619 error("#else without matching #if");
1620 if (ifdef_stack_ptr
[-1] & 2)
1621 error("#else after #else");
1622 c
= (ifdef_stack_ptr
[-1] ^= 3);
1624 } else if (tok
== TOK_ELIF
) {
1625 if (ifdef_stack_ptr
== ifdef_stack
)
1626 error("#elif without matching #if");
1627 c
= ifdef_stack_ptr
[-1];
1629 error("#elif after #else");
1630 /* last #if/#elif expression was true: we skip */
1633 c
= expr_preprocess();
1634 ifdef_stack_ptr
[-1] = c
;
1641 } else if (tok
== TOK_ENDIF
) {
1642 if (ifdef_stack_ptr
== ifdef_stack
)
1643 error("#endif without matching #if");
1645 } else if (tok
== TOK_LINE
) {
1647 if (tok
!= TOK_CINT
)
1649 file
->line_num
= tokc
.i
;
1655 pstrcpy(file
->filename
, sizeof(file
->filename
),
1656 get_tok_str(tok
, &tokc
));
1658 } else if (tok
== TOK_ERROR
) {
1661 /* ignore other preprocess commands or #! for C scripts */
1662 while (ch
!= '\n' && ch
!= -1)
1666 /* read a number in base b */
1672 if (ch
>= 'a' && ch
<= 'f')
1674 else if (ch
>= 'A' && ch
<= 'F')
1680 if (t
< 0 || t
>= b
)
1688 /* read a character for string or char constant and eval escape codes */
1697 /* at most three octal digits */
1701 c
= c
* 8 + ch
- '0';
1704 c
= c
* 8 + ch
- '0';
1709 } else if (ch
== 'x') {
1727 else if (ch
== 'e' && gnu_ext
)
1729 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1732 error("invalid escaped char");
1739 /* we use 64 bit numbers */
1742 /* bn = (bn << shift) | or_val */
1743 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1747 for(i
=0;i
<BN_SIZE
;i
++) {
1749 bn
[i
] = (v
<< shift
) | or_val
;
1750 or_val
= v
>> (32 - shift
);
1754 void bn_zero(unsigned int *bn
)
1757 for(i
=0;i
<BN_SIZE
;i
++) {
1762 void parse_number(void)
1764 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1766 unsigned int bn
[BN_SIZE
];
1776 /* special dot handling */
1777 if (ch
>= '0' && ch
<= '9') {
1778 goto float_frac_parse
;
1779 } else if (ch
== '.') {
1790 } else if (t
== '0') {
1791 if (ch
== 'x' || ch
== 'X') {
1795 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1801 /* parse all digits. cannot check octal numbers at this stage
1802 because of floating point constants */
1804 if (ch
>= 'a' && ch
<= 'f')
1806 else if (ch
>= 'A' && ch
<= 'F')
1814 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1816 error("number too long");
1822 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1823 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1825 /* NOTE: strtox should support that for hexa numbers, but
1826 non ISOC99 libcs do not support it, so we prefer to do
1828 /* hexadecimal or binary floats */
1829 /* XXX: handle overflows */
1841 } else if (t
>= 'a') {
1843 } else if (t
>= 'A') {
1848 bn_lshift(bn
, shift
, t
);
1855 if (t
>= 'a' && t
<= 'f') {
1857 } else if (t
>= 'A' && t
<= 'F') {
1859 } else if (t
>= '0' && t
<= '9') {
1865 error("invalid digit");
1866 bn_lshift(bn
, shift
, t
);
1871 if (ch
!= 'p' && ch
!= 'P')
1872 error("exponent expected");
1878 } else if (ch
== '-') {
1882 if (ch
< '0' || ch
> '9')
1883 error("exponent digits expected");
1884 while (ch
>= '0' && ch
<= '9') {
1885 exp_val
= exp_val
* 10 + ch
- '0';
1888 exp_val
= exp_val
* s
;
1890 /* now we can generate the number */
1891 /* XXX: should patch directly float number */
1892 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1893 d
= ldexp(d
, exp_val
- frac_bits
);
1898 /* float : should handle overflow */
1900 } else if (t
== 'L') {
1903 /* XXX: not large enough */
1904 tokc
.ld
= (long double)d
;
1910 /* decimal floats */
1912 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1917 while (ch
>= '0' && ch
<= '9') {
1918 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1924 if (ch
== 'e' || ch
== 'E') {
1925 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1929 if (ch
== '-' || ch
== '+') {
1930 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1935 if (ch
< '0' || ch
> '9')
1936 error("exponent digits expected");
1937 while (ch
>= '0' && ch
<= '9') {
1938 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1950 tokc
.f
= strtof(token_buf
, NULL
);
1951 } else if (t
== 'L') {
1954 tokc
.ld
= strtold(token_buf
, NULL
);
1957 tokc
.d
= strtod(token_buf
, NULL
);
1961 unsigned long long n
, n1
;
1964 /* integer number */
1967 if (b
== 10 && *q
== '0') {
1974 /* no need for checks except for base 10 / 8 errors */
1977 } else if (t
>= 'a') {
1979 } else if (t
>= 'A') {
1984 error("invalid digit");
1988 /* detect overflow */
1990 error("integer constant overflow");
1993 /* XXX: not exactly ANSI compliant */
1994 if ((n
& 0xffffffff00000000LL
) != 0) {
1999 } else if (n
> 0x7fffffff) {
2009 error("three 'l' in integer constant");
2012 if (tok
== TOK_CINT
)
2014 else if (tok
== TOK_CUINT
)
2018 } else if (t
== 'U') {
2019 if (tok
== TOK_CINT
)
2021 else if (tok
== TOK_CLLONG
)
2028 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2036 /* return next token without macro substitution */
2037 void next_nomacro1(void)
2045 while (ch
== '\n') {
2047 while (ch
== ' ' || ch
== '\t')
2050 /* preprocessor command if # at start of line after
2055 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2073 while (isid(ch
) || isnum(ch
)) {
2074 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2075 error("ident too long");
2080 ts
= tok_alloc(token_buf
, q
- token_buf
);
2082 } else if (isnum(ch
) || ch
== '.') {
2084 } else if (ch
== '\'') {
2092 } else if (ch
== '\"') {
2097 while (ch
!= '\"') {
2100 error("unterminated string");
2101 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2102 error("string too long");
2106 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2109 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2114 if (*q
== tok
&& q
[1] == ch
) {
2117 /* three chars tests */
2118 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2123 } else if (tok
== TOK_DOTS
) {
2125 error("parse error");
2132 /* single char substitutions */
2135 else if (tok
== '>')
2140 /* return next token without macro substitution. Can read input from
2148 tok
= tok_get(¯o_ptr
, &tokc
);
2149 if (tok
== TOK_LINENUM
) {
2150 file
->line_num
= tokc
.i
;
2159 /* substitute args in macro_str and return allocated string */
2160 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2162 int *st
, last_tok
, t
, notfirst
;
2171 t
= tok_get(¯o_str
, &cval
);
2176 t
= tok_get(¯o_str
, &cval
);
2179 s
= sym_find2(args
, t
);
2181 token_buf
[0] = '\0';
2186 pstrcat(token_buf
, sizeof(token_buf
), " ");
2187 t
= tok_get(&st
, &cval
);
2188 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2192 printf("stringize: %s\n", token_buf
);
2195 ts
= tok_alloc(token_buf
, 0);
2197 tok_str_add2(&str
, TOK_STR
, &cval
);
2199 tok_str_add2(&str
, t
, &cval
);
2201 } else if (t
>= TOK_IDENT
) {
2202 s
= sym_find2(args
, t
);
2205 /* if '##' is present before or after, no arg substitution */
2206 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2207 /* special case for var arg macros : ## eats the
2208 ',' if empty VA_ARGS riable. */
2209 /* XXX: test of the ',' is not 100%
2210 reliable. should fix it to avoid security
2212 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2213 last_tok
== TOK_TWOSHARPS
&&
2214 str
.len
>= 2&& str
.str
[str
.len
- 2] == ',') {
2215 /* suppress ',' '##' */
2219 tok_str_add(&str
, *st
++);
2222 macro_subst(&str
, nested_list
, st
);
2225 tok_str_add(&str
, t
);
2228 tok_str_add2(&str
, t
, &cval
);
2232 tok_str_add(&str
, 0);
2236 /* handle the '##' operator */
2237 int *macro_twosharps(int *macro_str
)
2244 TokenString macro_str1
;
2246 tok_str_new(¯o_str1
);
2252 while (*macro_ptr
== TOK_TWOSHARPS
) {
2254 macro_ptr1
= macro_ptr
;
2257 t
= tok_get(¯o_ptr
, &cval
);
2258 /* XXX: we handle only most common cases:
2259 ident + ident or ident + number */
2260 if (tok
>= TOK_IDENT
&&
2261 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2262 p
= get_tok_str(tok
, &tokc
);
2263 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2264 p
= get_tok_str(t
, &cval
);
2265 pstrcat(token_buf
, sizeof(token_buf
), p
);
2266 ts
= tok_alloc(token_buf
, 0);
2267 tok
= ts
->tok
; /* modify current token */
2269 /* cannot merge tokens: skip '##' */
2270 macro_ptr
= macro_ptr1
;
2275 tok_str_add2(¯o_str1
, tok
, &tokc
);
2277 tok_str_add(¯o_str1
, 0);
2278 return macro_str1
.str
;
2281 /* do macro substitution of macro_str and add result to
2282 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2283 substituted. 'nested_list' is the list of all macros we got inside
2284 to avoid recursing. */
2285 void macro_subst(TokenString
*tok_str
,
2286 Sym
**nested_list
, int *macro_str
)
2288 Sym
*s
, *args
, *sa
, *sa1
;
2289 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2290 int mstr_allocated
, *macro_str1
;
2294 saved_macro_ptr
= macro_ptr
;
2295 macro_ptr
= macro_str
;
2298 /* first scan for '##' operator handling */
2299 macro_str1
= macro_twosharps(macro_str
);
2300 macro_ptr
= macro_str1
;
2307 /* special macros */
2308 if (tok
== TOK___LINE__
) {
2309 cval
.i
= file
->line_num
;
2310 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2311 } else if (tok
== TOK___FILE__
) {
2312 cval
.ts
= tok_alloc(file
->filename
, 0);
2313 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2314 } else if (tok
== TOK___DATE__
) {
2315 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2316 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2317 } else if (tok
== TOK___TIME__
) {
2318 cval
.ts
= tok_alloc("00:00:00", 0);
2319 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2320 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2321 /* if symbol is a macro, prepare substitution */
2322 /* if nested substitution, do nothing */
2323 if (sym_find2(*nested_list
, tok
))
2327 if (s
->t
== MACRO_FUNC
) {
2328 /* NOTE: we do not use next_nomacro to avoid eating the
2329 next token. XXX: find better solution */
2333 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2337 if (t
!= '(') /* no macro subst */
2340 /* argument macro */
2345 /* NOTE: empty args are allowed, except if no args */
2347 /* handle '()' case */
2348 if (!args
&& tok
== ')')
2351 error("macro '%s' used with too many args",
2352 get_tok_str(s
->v
, 0));
2355 /* NOTE: non zero sa->t indicates VA_ARGS */
2356 while ((parlevel
> 0 ||
2358 (tok
!= ',' || sa
->t
))) &&
2362 else if (tok
== ')')
2364 tok_str_add2(&str
, tok
, &tokc
);
2367 tok_str_add(&str
, 0);
2368 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2371 /* special case for gcc var args: add an empty
2372 var arg argument if it is omitted */
2373 if (sa
&& sa
->t
&& gnu_ext
)
2383 error("macro '%s' used with too few args",
2384 get_tok_str(s
->v
, 0));
2387 /* now subst each arg */
2388 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2399 sym_push2(nested_list
, s
->v
, 0, 0);
2400 macro_subst(tok_str
, nested_list
, mstr
);
2401 /* pop nested defined symbol */
2403 *nested_list
= sa1
->prev
;
2409 /* no need to add if reading input stream */
2412 tok_str_add2(tok_str
, tok
, &tokc
);
2414 /* only replace one macro while parsing input stream */
2418 macro_ptr
= saved_macro_ptr
;
2423 /* return next token with macro substitution */
2429 /* special 'ungettok' case for label parsing */
2437 /* if not reading from macro substituted string, then try
2439 /* XXX: optimize non macro case */
2442 macro_subst(&str
, &nested_list
, NULL
);
2444 tok_str_add(&str
, 0);
2445 macro_ptr
= str
.str
;
2446 macro_ptr_allocated
= str
.str
;
2454 /* end of macro string: free it */
2455 free(macro_ptr_allocated
);
2462 printf("token = %s\n", get_tok_str(tok
, tokc
));
2466 void swap(int *p
, int *q
)
2474 void vsetc(int t
, int r
, CValue
*vc
)
2476 if (vtop
>= vstack
+ VSTACK_SIZE
)
2477 error("memory full");
2478 /* cannot let cpu flags if other instruction are generated */
2479 /* XXX: VT_JMP test too ? */
2480 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2485 vtop
->r2
= VT_CONST
;
2489 /* push integer constant */
2494 vsetc(VT_INT
, VT_CONST
, &cval
);
2497 /* Return a static symbol pointing to a section */
2498 static Sym
*get_sym_ref(int t
, Section
*sec
,
2499 unsigned long offset
, unsigned long size
)
2505 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2506 sym
->r
= VT_CONST
| VT_SYM
;
2507 put_extern_sym(sym
, sec
, offset
);
2511 /* push a reference to a section offset by adding a dummy symbol */
2513 void vpush_ref(int t
, Section
*sec
, unsigned long offset
)
2517 cval
.sym
= get_sym_ref(t
, sec
, offset
, 0);
2518 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2521 /* push a reference to symbol v */
2522 void vpush_sym(int t
, int v
)
2527 sym
= external_sym(v
, t
, 0);
2529 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2532 void vset(int t
, int r
, int v
)
2549 void vpushv(SValue
*v
)
2551 if (vtop
>= vstack
+ VSTACK_SIZE
)
2552 error("memory full");
2562 /* save r to the memory stack, and mark it as being free */
2563 void save_reg(int r
)
2565 int l
, i
, saved
, t
, size
, align
;
2568 /* modify all stack values */
2571 for(p
=vstack
;p
<=vtop
;p
++) {
2572 i
= p
->r
& VT_VALMASK
;
2573 if ((p
->r
& VT_VALMASK
) == r
||
2574 (p
->r2
& VT_VALMASK
) == r
) {
2575 /* must save value on stack if not already done */
2577 /* store register in the stack */
2579 if ((p
->r
& VT_LVAL
) ||
2580 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2582 size
= type_size(t
, &align
);
2583 loc
= (loc
- size
) & -align
;
2585 sv
.r
= VT_LOCAL
| VT_LVAL
;
2588 #ifdef TCC_TARGET_I386
2589 /* x86 specific: need to pop fp register ST0 if saved */
2591 o(0xd9dd); /* fstp %st(1) */
2594 /* special long long case */
2595 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2602 /* mark that stack entry as being saved on the stack */
2614 /* find a free register of class 'rc'. If none, save one register */
2620 /* find a free register */
2621 for(r
=0;r
<NB_REGS
;r
++) {
2622 if (reg_classes
[r
] & rc
) {
2623 for(p
=vstack
;p
<=vtop
;p
++) {
2624 if ((p
->r
& VT_VALMASK
) == r
||
2625 (p
->r2
& VT_VALMASK
) == r
)
2633 /* no register left : free the first one on the stack (VERY
2634 IMPORTANT to start from the bottom to ensure that we don't
2635 spill registers used in gen_opi()) */
2636 for(p
=vstack
;p
<=vtop
;p
++) {
2637 r
= p
->r
& VT_VALMASK
;
2638 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2646 /* save registers up to (vtop - n) stack entry */
2647 void save_regs(int n
)
2652 for(p
= vstack
;p
<= p1
; p
++) {
2653 r
= p
->r
& VT_VALMASK
;
2660 /* move register 's' to 'r', and flush previous value of r to memory
2662 void move_reg(int r
, int s
)
2675 /* get address of vtop (vtop MUST BE an lvalue) */
2678 vtop
->r
&= ~VT_LVAL
;
2679 /* tricky: if saved lvalue, then we can go back to lvalue */
2680 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2681 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2684 #ifdef CONFIG_TCC_BCHECK
2685 /* generate lvalue bound code */
2690 vtop
->r
&= ~VT_MUSTBOUND
;
2691 /* if lvalue, then use checking code before dereferencing */
2692 if (vtop
->r
& VT_LVAL
) {
2693 /* if not VT_BOUNDED value, then make one */
2694 if (!(vtop
->r
& VT_BOUNDED
)) {
2695 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2698 gen_bounded_ptr_add();
2699 vtop
->r
|= lval_type
;
2701 /* then check for dereferencing */
2702 gen_bounded_ptr_deref();
2707 /* store vtop a register belonging to class 'rc'. lvalues are
2708 converted to values. Cannot be used if cannot be converted to
2709 register value (such as structures). */
2712 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2713 unsigned long long ll
;
2715 /* NOTE: get_reg can modify vstack[] */
2716 if (vtop
->t
& VT_BITFIELD
) {
2717 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2718 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2719 /* remove bit field info to avoid loops */
2720 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2721 /* generate shifts */
2722 vpushi(32 - (bit_pos
+ bit_size
));
2724 vpushi(32 - bit_size
);
2725 /* NOTE: transformed to SHR if unsigned */
2729 if (is_float(vtop
->t
) &&
2730 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2734 /* XXX: unify with initializers handling ? */
2735 /* CPUs usually cannot use float constants, so we store them
2736 generically in data segment */
2737 size
= type_size(vtop
->t
, &align
);
2738 data_offset
= data_section
->data_ptr
- data_section
->data
;
2739 data_offset
= (data_offset
+ align
- 1) & -align
;
2740 /* XXX: not portable yet */
2743 ((int *)(data_section
->data
+ data_offset
))[i
] = vtop
->c
.tab
[i
];
2746 sym
= sym_push1(&global_stack
, v
, vtop
->t
| VT_STATIC
, 0);
2747 sym
->r
= VT_CONST
| VT_SYM
;
2748 put_extern_sym(sym
, data_section
, data_offset
);
2750 vtop
->r
|= VT_LVAL
| VT_SYM
;
2752 data_offset
+= size
<< 2;
2753 data_section
->data_ptr
= data_section
->data
+ data_offset
;
2755 #ifdef CONFIG_TCC_BCHECK
2756 if (vtop
->r
& VT_MUSTBOUND
)
2760 r
= vtop
->r
& VT_VALMASK
;
2761 /* need to reload if:
2763 - lvalue (need to dereference pointer)
2764 - already a register, but not in the right class */
2765 if (r
>= VT_CONST
||
2766 (vtop
->r
& VT_LVAL
) ||
2767 !(reg_classes
[r
] & rc
) ||
2768 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2769 !(reg_classes
[vtop
->r2
] & rc
))) {
2771 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2772 /* two register type load : expand to two words
2774 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2777 vtop
->c
.ui
= ll
; /* first word */
2779 vtop
->r
= r
; /* save register value */
2780 vpushi(ll
>> 32); /* second word */
2781 } else if (r
>= VT_CONST
||
2782 (vtop
->r
& VT_LVAL
)) {
2783 /* load from memory */
2786 vtop
[-1].r
= r
; /* save register value */
2787 /* increment pointer to get second word */
2794 /* move registers */
2797 vtop
[-1].r
= r
; /* save register value */
2798 vtop
->r
= vtop
[-1].r2
;
2800 /* allocate second register */
2807 /* write second register */
2809 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2811 /* lvalue of scalar type : need to use lvalue type
2812 because of possible cast */
2815 /* compute memory access type */
2816 if (vtop
->r
& VT_LVAL_BYTE
)
2818 else if (vtop
->r
& VT_LVAL_SHORT
)
2820 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2824 /* restore wanted type */
2827 /* one register type load */
2836 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2837 void gv2(int rc1
, int rc2
)
2839 /* generate more generic register first */
2845 /* test if reload is needed for first register */
2846 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2856 /* test if reload is needed for first register */
2857 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2863 /* expand long long on stack in two int registers */
2868 u
= vtop
->t
& VT_UNSIGNED
;
2871 vtop
[0].r
= vtop
[-1].r2
;
2872 vtop
[0].r2
= VT_CONST
;
2873 vtop
[-1].r2
= VT_CONST
;
2874 vtop
[0].t
= VT_INT
| u
;
2875 vtop
[-1].t
= VT_INT
| u
;
2878 /* build a long long from two ints */
2881 gv2(RC_INT
, RC_INT
);
2882 vtop
[-1].r2
= vtop
[0].r
;
2887 /* rotate n first stack elements to the bottom */
2894 for(i
=-n
+1;i
!=0;i
++)
2895 vtop
[i
] = vtop
[i
+1];
2899 /* pop stack value */
2903 v
= vtop
->r
& VT_VALMASK
;
2904 #ifdef TCC_TARGET_I386
2905 /* for x86, we need to pop the FP stack */
2907 o(0xd9dd); /* fstp %st(1) */
2910 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2911 /* need to put correct jump if && or || without test */
2917 /* convert stack entry to register and duplicate its value in another
2925 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2932 /* stack: H L L1 H1 */
2940 /* duplicate value */
2951 load(r1
, &sv
); /* move r to r1 */
2953 /* duplicates value */
2958 /* generate CPU independent (unsigned) long long operations */
2959 void gen_opl(int op
)
2961 int t
, a
, b
, op1
, c
, i
;
2969 func
= TOK___divdi3
;
2972 func
= TOK___udivdi3
;
2975 func
= TOK___moddi3
;
2978 func
= TOK___umoddi3
;
2980 /* call generic long long function */
2981 gfunc_start(&gf
, FUNC_CDECL
);
2984 vpush_sym(func_old_type
, func
);
2988 vtop
->r2
= REG_LRET
;
3001 /* stack: L1 H1 L2 H2 */
3006 vtop
[-2] = vtop
[-3];
3009 /* stack: H1 H2 L1 L2 */
3015 /* stack: H1 H2 L1 L2 ML MH */
3018 /* stack: ML MH H1 H2 L1 L2 */
3022 /* stack: ML MH H1 L2 H2 L1 */
3027 /* stack: ML MH M1 M2 */
3030 } else if (op
== '+' || op
== '-') {
3031 /* XXX: add non carry method too (for MIPS or alpha) */
3037 /* stack: H1 H2 (L1 op L2) */
3040 gen_op(op1
+ 1); /* TOK_xxxC2 */
3043 /* stack: H1 H2 (L1 op L2) */
3046 /* stack: (L1 op L2) H1 H2 */
3048 /* stack: (L1 op L2) (H1 op H2) */
3056 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3061 /* stack: L H shift */
3063 /* constant: simpler */
3064 /* NOTE: all comments are for SHL. the other cases are
3065 done by swaping words */
3076 if (op
!= TOK_SAR
) {
3106 /* XXX: should provide a faster fallback on x86 ? */
3109 func
= TOK___sardi3
;
3112 func
= TOK___shrdi3
;
3115 func
= TOK___shldi3
;
3121 /* compare operations */
3127 /* stack: L1 H1 L2 H2 */
3129 vtop
[-1] = vtop
[-2];
3131 /* stack: L1 L2 H1 H2 */
3134 /* when values are equal, we need to compare low words. since
3135 the jump is inverted, we invert the test too. */
3138 else if (op1
== TOK_GT
)
3140 else if (op1
== TOK_ULT
)
3142 else if (op1
== TOK_UGT
)
3147 if (op1
!= TOK_NE
) {
3151 /* generate non equal test */
3152 /* XXX: NOT PORTABLE yet */
3156 #ifdef TCC_TARGET_I386
3157 b
= psym(0x850f, 0);
3159 error("not implemented");
3167 vset(VT_INT
, VT_JMPI
, a
);
3172 /* handle integer constant optimizations and various machine
3174 void gen_opic(int op
)
3181 /* currently, we cannot do computations with forward symbols */
3182 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3183 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3187 case '+': v1
->c
.i
+= fc
; break;
3188 case '-': v1
->c
.i
-= fc
; break;
3189 case '&': v1
->c
.i
&= fc
; break;
3190 case '^': v1
->c
.i
^= fc
; break;
3191 case '|': v1
->c
.i
|= fc
; break;
3192 case '*': v1
->c
.i
*= fc
; break;
3199 /* if division by zero, generate explicit division */
3202 error("division by zero in constant");
3206 default: v1
->c
.i
/= fc
; break;
3207 case '%': v1
->c
.i
%= fc
; break;
3208 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3209 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3212 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3213 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3214 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3216 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3217 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3218 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3219 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3220 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3221 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3222 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3223 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3224 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3225 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3227 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3228 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3234 /* if commutative ops, put c2 as constant */
3235 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3236 op
== '|' || op
== '*')) {
3241 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3244 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3245 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3251 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3252 /* try to use shifts instead of muls or divs */
3253 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3262 else if (op
== TOK_PDIV
)
3270 /* call low level op generator */
3276 /* generate a floating point operation with constant propagation */
3277 void gen_opif(int op
)
3285 /* currently, we cannot do computations with forward symbols */
3286 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3287 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3289 if (v1
->t
== VT_FLOAT
) {
3292 } else if (v1
->t
== VT_DOUBLE
) {
3300 /* NOTE: we only do constant propagation if finite number (not
3301 NaN or infinity) (ANSI spec) */
3302 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3306 case '+': f1
+= f2
; break;
3307 case '-': f1
-= f2
; break;
3308 case '*': f1
*= f2
; break;
3312 error("division by zero in constant");
3317 /* XXX: also handles tests ? */
3321 /* XXX: overflow test ? */
3322 if (v1
->t
== VT_FLOAT
) {
3324 } else if (v1
->t
== VT_DOUBLE
) {
3337 int pointed_size(int t
)
3339 return type_size(pointed_type(t
), &t
);
3343 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3345 char buf1
[256], buf2
[256];
3349 if (!is_compatible_types(t1
, t2
)) {
3350 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3351 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3352 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3357 /* generic gen_op: handles types problems */
3360 int u
, t1
, t2
, bt1
, bt2
, t
;
3364 bt1
= t1
& VT_BTYPE
;
3365 bt2
= t2
& VT_BTYPE
;
3367 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3368 /* at least one operand is a pointer */
3369 /* relationnal op: must be both pointers */
3370 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3371 // check_pointer_types(vtop, vtop - 1);
3372 /* pointers are handled are unsigned */
3373 t
= VT_INT
| VT_UNSIGNED
;
3376 /* if both pointers, then it must be the '-' op */
3377 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3378 (t2
& VT_BTYPE
) == VT_PTR
) {
3380 error("cannot use pointers here");
3381 // check_pointer_types(vtop - 1, vtop);
3382 /* XXX: check that types are compatible */
3383 u
= pointed_size(t1
);
3385 /* set to integer type */
3390 /* exactly one pointer : must be '+' or '-'. */
3391 if (op
!= '-' && op
!= '+')
3392 error("cannot use pointers here");
3393 /* Put pointer as first operand */
3394 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3398 /* XXX: cast to int ? (long long case) */
3399 vpushi(pointed_size(vtop
[-1].t
));
3401 #ifdef CONFIG_TCC_BCHECK
3402 /* if evaluating constant expression, no code should be
3403 generated, so no bound check */
3404 if (do_bounds_check
&& !const_wanted
) {
3405 /* if bounded pointers, we generate a special code to
3412 gen_bounded_ptr_add();
3418 /* put again type if gen_opic() swaped operands */
3421 } else if (is_float(bt1
) || is_float(bt2
)) {
3422 /* compute bigger type and do implicit casts */
3423 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3425 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3430 /* floats can only be used for a few operations */
3431 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3432 (op
< TOK_ULT
|| op
> TOK_GT
))
3433 error("invalid operands for binary operation");
3435 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3436 /* cast to biggest op */
3438 /* convert to unsigned if it does not fit in a long long */
3439 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3440 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3444 /* integer operations */
3446 /* convert to unsigned if it does not fit in an integer */
3447 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3448 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3451 /* XXX: currently, some unsigned operations are explicit, so
3452 we modify them here */
3453 if (t
& VT_UNSIGNED
) {
3460 else if (op
== TOK_LT
)
3462 else if (op
== TOK_GT
)
3464 else if (op
== TOK_LE
)
3466 else if (op
== TOK_GE
)
3472 /* special case for shifts and long long: we keep the shift as
3474 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3480 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3484 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3485 /* relationnal op: the result is an int */
3493 /* generic itof for unsigned long long case */
3494 void gen_cvt_itof1(int t
)
3498 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3499 (VT_LLONG
| VT_UNSIGNED
)) {
3501 gfunc_start(&gf
, FUNC_CDECL
);
3504 vpush_sym(func_old_type
, TOK___ulltof
);
3505 else if (t
== VT_DOUBLE
)
3506 vpush_sym(func_old_type
, TOK___ulltod
);
3508 vpush_sym(func_old_type
, TOK___ulltold
);
3517 /* generic ftoi for unsigned long long case */
3518 void gen_cvt_ftoi1(int t
)
3523 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3524 /* not handled natively */
3525 gfunc_start(&gf
, FUNC_CDECL
);
3526 st
= vtop
->t
& VT_BTYPE
;
3529 vpush_sym(func_old_type
, TOK___fixunssfdi
);
3530 else if (st
== VT_DOUBLE
)
3531 vpush_sym(func_old_type
, TOK___fixunsdfdi
);
3533 vpush_sym(func_old_type
, TOK___fixunsxfdi
);
3537 vtop
->r2
= REG_LRET
;
3543 /* force char or short cast */
3544 void force_charshort_cast(int t
)
3548 /* XXX: add optimization if lvalue : just change type and offset */
3553 if (t
& VT_UNSIGNED
) {
3554 vpushi((1 << bits
) - 1);
3565 /* cast 'vtop' to 't' type */
3566 void gen_cast(int t
)
3568 int sbt
, dbt
, sf
, df
, c
;
3570 /* special delayed cast for char/short */
3571 /* XXX: in some cases (multiple cascaded casts), it may still
3573 if (vtop
->r
& VT_MUSTCAST
) {
3574 vtop
->r
&= ~VT_MUSTCAST
;
3575 force_charshort_cast(vtop
->t
);
3578 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3579 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3584 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3586 /* convert from fp to fp */
3588 /* constant case: we can do it now */
3589 /* XXX: in ISOC, cannot do it if error in convert */
3590 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3591 vtop
->c
.f
= (float)vtop
->c
.d
;
3592 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3593 vtop
->c
.f
= (float)vtop
->c
.ld
;
3594 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3595 vtop
->c
.d
= (double)vtop
->c
.f
;
3596 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3597 vtop
->c
.d
= (double)vtop
->c
.ld
;
3598 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3599 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3600 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3601 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3603 /* non constant case: generate code */
3607 /* convert int to fp */
3610 case VT_LLONG
| VT_UNSIGNED
:
3612 /* XXX: add const cases for long long */
3614 case VT_INT
| VT_UNSIGNED
:
3616 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3617 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3618 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3623 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3624 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3625 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3634 /* convert fp to int */
3635 /* we handle char/short/etc... with generic code */
3636 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3637 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3642 case VT_LLONG
| VT_UNSIGNED
:
3644 /* XXX: add const cases for long long */
3646 case VT_INT
| VT_UNSIGNED
:
3648 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3649 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3650 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3656 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3657 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3658 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3666 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3667 /* additionnal cast for char/short/bool... */
3671 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3672 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3673 /* scalar to long long */
3675 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3676 vtop
->c
.ll
= vtop
->c
.ui
;
3678 vtop
->c
.ll
= vtop
->c
.i
;
3680 /* machine independant conversion */
3682 /* generate high word */
3683 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3691 /* patch second register */
3692 vtop
[-1].r2
= vtop
->r
;
3696 } else if (dbt
== VT_BOOL
) {
3697 /* scalar to bool */
3700 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3701 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3702 force_charshort_cast(t
);
3703 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3705 if (sbt
== VT_LLONG
) {
3706 /* from long long: just take low order word */
3710 /* if lvalue and single word type, nothing to do because
3711 the lvalue already contains the real type size (see
3712 VT_LVAL_xxx constants) */
3718 /* return type size. Put alignment at 'a' */
3719 int type_size(int t
, int *a
)
3725 if (bt
== VT_STRUCT
) {
3727 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3728 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3730 } else if (bt
== VT_PTR
) {
3732 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3733 return type_size(s
->t
, a
) * s
->c
;
3738 } else if (bt
== VT_LDOUBLE
) {
3740 return LDOUBLE_SIZE
;
3741 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3744 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3747 } else if (bt
== VT_SHORT
) {
3751 /* char, void, function, _Bool */
3757 /* return the pointed type of t */
3758 int pointed_type(int t
)
3761 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3762 return s
->t
| (t
& ~VT_TYPE
);
3765 int mk_pointer(int t
)
3769 sym_push(p
, t
, 0, -1);
3770 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3773 int is_compatible_types(int t1
, int t2
)
3780 bt1
= t1
& VT_BTYPE
;
3781 bt2
= t2
& VT_BTYPE
;
3782 if (bt1
== VT_PTR
) {
3783 t1
= pointed_type(t1
);
3784 /* if function, then convert implicitely to function pointer */
3785 if (bt2
!= VT_FUNC
) {
3788 t2
= pointed_type(t2
);
3790 /* void matches everything */
3793 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3795 return is_compatible_types(t1
, t2
);
3796 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3798 } else if (bt1
== VT_FUNC
) {
3801 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3802 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3803 if (!is_compatible_types(s1
->t
, s2
->t
))
3805 /* XXX: not complete */
3806 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3810 while (s1
!= NULL
) {
3813 if (!is_compatible_types(s1
->t
, s2
->t
))
3822 /* XXX: not complete */
3827 /* print a type. If 'varstr' is not NULL, then the variable is also
3828 printed in the type */
3830 /* XXX: add array and function pointers */
3831 void type_to_str(char *buf
, int buf_size
,
3832 int t
, const char *varstr
)
3842 if (t
& VT_UNSIGNED
)
3843 pstrcat(buf
, buf_size
, "unsigned ");
3873 tstr
= "long double";
3875 pstrcat(buf
, buf_size
, tstr
);
3879 if (bt
== VT_STRUCT
)
3883 pstrcat(buf
, buf_size
, tstr
);
3884 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3885 if (v
>= SYM_FIRST_ANOM
)
3886 pstrcat(buf
, buf_size
, "<anonymous>");
3888 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3891 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3892 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3893 pstrcat(buf
, buf_size
, "(");
3895 while (sa
!= NULL
) {
3896 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3897 pstrcat(buf
, buf_size
, buf1
);
3900 pstrcat(buf
, buf_size
, ", ");
3902 pstrcat(buf
, buf_size
, ")");
3905 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3906 pstrcpy(buf1
, sizeof(buf1
), "*");
3908 pstrcat(buf1
, sizeof(buf1
), varstr
);
3909 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3913 pstrcat(buf
, buf_size
, " ");
3914 pstrcat(buf
, buf_size
, varstr
);
3919 /* verify type compatibility to store vtop in 'dt' type, and generate
3921 void gen_assign_cast(int dt
)
3924 char buf1
[256], buf2
[256];
3926 st
= vtop
->t
; /* source type */
3927 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3928 /* special cases for pointers */
3929 /* a function is implicitely a function pointer */
3930 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3931 if (!is_compatible_types(pointed_type(dt
), st
))
3936 /* '0' can also be a pointer */
3937 if ((st
& VT_BTYPE
) == VT_INT
&&
3938 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3942 if (!is_compatible_types(dt
, st
)) {
3944 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3945 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3946 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3952 /* store vtop in lvalue pushed on stack */
3955 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3959 sbt
= vtop
->t
& VT_BTYPE
;
3960 dbt
= ft
& VT_BTYPE
;
3961 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3962 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3963 /* optimize char/short casts */
3964 delayed_cast
= VT_MUSTCAST
;
3965 vtop
->t
= ft
& VT_TYPE
;
3968 gen_assign_cast(ft
& VT_TYPE
);
3971 if (sbt
== VT_STRUCT
) {
3972 /* if structure, only generate pointer */
3973 /* structure assignment : generate memcpy */
3974 /* XXX: optimize if small size */
3976 gfunc_start(&gf
, FUNC_CDECL
);
3978 size
= type_size(vtop
->t
, &align
);
3992 vpush_sym(func_old_type
, TOK_memcpy
);
3994 /* leave source on stack */
3995 } else if (ft
& VT_BITFIELD
) {
3996 /* bitfield store handling */
3997 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3998 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3999 /* remove bit field info to avoid loops */
4000 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4002 /* duplicate destination */
4004 vtop
[-1] = vtop
[-2];
4006 /* mask and shift source */
4007 vpushi((1 << bit_size
) - 1);
4011 /* load destination, mask and or with source */
4013 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4019 #ifdef CONFIG_TCC_BCHECK
4020 /* bound check case */
4021 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4030 r
= gv(rc
); /* generate value */
4031 /* if lvalue was saved on stack, must read it */
4032 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4034 t
= get_reg(RC_INT
);
4036 sv
.r
= VT_LOCAL
| VT_LVAL
;
4037 sv
.c
.ul
= vtop
[-1].c
.ul
;
4039 vtop
[-1].r
= t
| VT_LVAL
;
4042 /* two word case handling : store second register at word + 4 */
4043 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4045 /* convert to int to increment easily */
4052 /* XXX: it works because r2 is spilled last ! */
4053 store(vtop
->r2
, vtop
- 1);
4056 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4057 vtop
->r
|= delayed_cast
;
4061 /* post defines POST/PRE add. c is the token ++ or -- */
4062 void inc(int post
, int c
)
4065 vdup(); /* save lvalue */
4067 gv_dup(); /* duplicate value */
4072 vpushi(c
- TOK_MID
);
4074 vstore(); /* store value */
4076 vpop(); /* if post op, return saved value */
4079 /* Parse GNUC __attribute__ extension. Currently, the following
4080 extensions are recognized:
4081 - aligned(n) : set data/function alignment.
4082 - section(x) : generate data/code in this section.
4083 - unused : currently ignored, but may be used someday.
4085 void parse_attribute(AttributeDef
*ad
)
4092 while (tok
!= ')') {
4093 if (tok
< TOK_IDENT
)
4094 expect("attribute name");
4099 case TOK___SECTION__
:
4102 expect("section name");
4103 ad
->section
= find_section(tokc
.ts
->str
);
4108 case TOK___ALIGNED__
:
4111 if (n
<= 0 || (n
& (n
- 1)) != 0)
4112 error("alignment must be a positive power of two");
4117 case TOK___UNUSED__
:
4118 /* currently, no need to handle it because tcc does not
4119 track unused objects */
4122 case TOK___NORETURN__
:
4123 /* currently, no need to handle it because tcc does not
4124 track unused objects */
4129 ad
->func_call
= FUNC_CDECL
;
4133 case TOK___STDCALL__
:
4134 ad
->func_call
= FUNC_STDCALL
;
4137 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4138 /* skip parameters */
4139 /* XXX: skip parenthesis too */
4142 while (tok
!= ')' && tok
!= -1)
4156 /* enum/struct/union declaration */
4157 int struct_decl(int u
)
4159 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4160 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4164 a
= tok
; /* save decl type */
4169 /* struct already defined ? return it */
4170 /* XXX: check consistency */
4171 s
= sym_find(v
| SYM_STRUCT
);
4174 error("invalid type");
4180 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4181 /* put struct/union/enum name in type */
4183 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4188 error("struct/union/enum already defined");
4189 /* cannot be empty */
4196 if (a
== TOK_ENUM
) {
4203 /* enum symbols have static storage */
4204 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4209 parse_btype(&b
, &ad
);
4214 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4215 if ((t
& VT_BTYPE
) == VT_FUNC
||
4216 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4217 error("invalid type for '%s'",
4218 get_tok_str(v
, NULL
));
4224 bit_size
= expr_const();
4225 /* XXX: handle v = 0 case for messages */
4227 error("negative width in bit-field '%s'",
4228 get_tok_str(v
, NULL
));
4229 if (v
&& bit_size
== 0)
4230 error("zero width for bit-field '%s'",
4231 get_tok_str(v
, NULL
));
4233 size
= type_size(t
, &align
);
4235 if (bit_size
>= 0) {
4240 error("bitfields must have scalar type");
4242 if (bit_size
> bsize
) {
4243 error("width of '%s' exceeds its type",
4244 get_tok_str(v
, NULL
));
4245 } else if (bit_size
== bsize
) {
4246 /* no need for bit fields */
4248 } else if (bit_size
== 0) {
4249 /* XXX: what to do if only padding in a
4251 /* zero size: means to pad */
4255 /* we do not have enough room ? */
4256 if ((bit_pos
+ bit_size
) > bsize
)
4259 /* XXX: handle LSB first */
4261 (bit_pos
<< VT_STRUCT_SHIFT
) |
4262 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4263 bit_pos
+= bit_size
;
4269 /* add new memory data only if starting
4271 if (lbit_pos
== 0) {
4272 if (a
== TOK_STRUCT
) {
4273 c
= (c
+ align
- 1) & -align
;
4281 if (align
> maxalign
)
4285 printf("add field %s offset=%d",
4286 get_tok_str(v
, NULL
), offset
);
4287 if (t
& VT_BITFIELD
) {
4288 printf(" pos=%d size=%d",
4289 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4290 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4294 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4298 if (tok
== ';' || tok
== -1)
4308 /* size for struct/union, dummy for enum */
4309 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4314 /* return 0 if no type declaration. otherwise, return the basic type
4317 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4319 int t
, u
, type_found
;
4322 memset(ad
, 0, sizeof(AttributeDef
));
4333 if ((t
& VT_BTYPE
) != 0)
4334 error("too many basic types");
4348 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4349 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4350 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4351 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4365 if ((t
& VT_BTYPE
) == VT_LONG
) {
4366 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4373 u
= struct_decl(VT_ENUM
);
4377 u
= struct_decl(VT_STRUCT
);
4380 /* type modifiers */
4385 case TOK___SIGNED__
:
4388 case TOK___INLINE__
:
4410 /* GNUC attribute */
4411 case TOK___ATTRIBUTE__
:
4412 parse_attribute(ad
);
4416 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4418 t
|= (s
->t
& ~VT_TYPEDEF
);
4425 /* long is never used as type */
4426 if ((t
& VT_BTYPE
) == VT_LONG
)
4427 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4432 int post_type(int t
, AttributeDef
*ad
)
4434 int p
, n
, pt
, l
, t1
;
4435 Sym
**plast
, *s
, *first
;
4439 /* function declaration */
4444 while (tok
!= ')') {
4445 /* read param name and compute offset */
4446 if (l
!= FUNC_OLD
) {
4447 if (!parse_btype(&pt
, &ad1
)) {
4449 error("invalid type");
4456 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4458 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4459 if ((pt
& VT_BTYPE
) == VT_VOID
)
4460 error("parameter declared as void");
4467 /* array must be transformed to pointer according to ANSI C */
4469 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4474 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4481 /* if no parameters, then old type prototype */
4485 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4486 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4487 /* we push a anonymous symbol which will contain the function prototype */
4489 s
= sym_push(p
, t
, ad
->func_call
, l
);
4491 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4492 } else if (tok
== '[') {
4493 /* array definition */
4499 error("invalid array size");
4502 /* parse next post type */
4503 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4504 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4506 /* we push a anonymous symbol which will contain the array
4509 sym_push(p
, t
, 0, n
);
4510 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4515 /* Read a type declaration (except basic type), and return the
4516 type. 'td' is a bitmask indicating which kind of type decl is
4517 expected. 't' should contain the basic type. 'ad' is the attribute
4518 definition of the basic type. It can be modified by type_decl(). */
4519 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4524 while (tok
== '*') {
4526 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4531 /* recursive type */
4532 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4535 /* XXX: this is not correct to modify 'ad' at this point, but
4536 the syntax is not clear */
4537 if (tok
== TOK___ATTRIBUTE__
)
4538 parse_attribute(ad
);
4539 u
= type_decl(ad
, v
, 0, td
);
4543 /* type identifier */
4544 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4548 if (!(td
& TYPE_ABSTRACT
))
4549 expect("identifier");
4553 /* append t at the end of u */
4554 t
= post_type(t
, ad
);
4555 if (tok
== TOK___ATTRIBUTE__
)
4556 parse_attribute(ad
);
4561 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4571 /* define a new external reference to a symbol 'v' of type 'u' */
4572 Sym
*external_sym(int v
, int u
, int r
)
4578 /* push forward reference */
4579 s
= sym_push1(&global_stack
,
4580 v
, u
| VT_EXTERN
, 0);
4581 s
->r
= r
| VT_CONST
| VT_SYM
;
4586 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4587 static int lvalue_type(int t
)
4594 else if (bt
== VT_SHORT
)
4598 if (t
& VT_UNSIGNED
)
4599 r
|= VT_LVAL_UNSIGNED
;
4603 /* indirection with full error checking and bound check */
4604 static void indir(void)
4606 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4608 if (vtop
->r
& VT_LVAL
)
4610 vtop
->t
= pointed_type(vtop
->t
);
4611 /* an array is never an lvalue */
4612 if (!(vtop
->t
& VT_ARRAY
)) {
4613 vtop
->r
|= lvalue_type(vtop
->t
);
4614 /* if bound checking, the referenced pointer must be checked */
4615 if (do_bounds_check
)
4616 vtop
->r
|= VT_MUSTBOUND
;
4620 /* pass a parameter to a function and do type checking and casting */
4621 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4624 func_type
= func
->c
;
4625 if (func_type
== FUNC_OLD
||
4626 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4627 /* default casting : only need to convert float to double */
4628 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4629 gen_cast(VT_DOUBLE
);
4630 } else if (arg
== NULL
) {
4631 error("too many arguments to function");
4633 gen_assign_cast(arg
->t
);
4640 int n
, t
, ft
, fc
, align
, size
, r
, data_offset
;
4645 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4648 } else if (tok
== TOK_CUINT
) {
4649 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4651 } else if (tok
== TOK_CLLONG
) {
4652 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4654 } else if (tok
== TOK_CULLONG
) {
4655 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4657 } else if (tok
== TOK_CFLOAT
) {
4658 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4660 } else if (tok
== TOK_CDOUBLE
) {
4661 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4663 } else if (tok
== TOK_CLDOUBLE
) {
4664 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4666 } else if (tok
== TOK___FUNC__
) {
4667 /* special function name identifier */
4668 /* generate (char *) type */
4669 data_offset
= data_section
->data_ptr
- data_section
->data
;
4670 vpush_ref(mk_pointer(VT_BYTE
), data_section
, data_offset
);
4671 strcpy(data_section
->data
+ data_offset
, funcname
);
4672 data_offset
+= strlen(funcname
) + 1;
4673 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4675 } else if (tok
== TOK_LSTR
) {
4678 } else if (tok
== TOK_STR
) {
4679 /* string parsing */
4682 type_size(t
, &align
);
4683 data_offset
= data_section
->data_ptr
- data_section
->data
;
4684 data_offset
= (data_offset
+ align
- 1) & -align
;
4686 /* we must declare it as an array first to use initializer parser */
4687 t
= VT_ARRAY
| mk_pointer(t
);
4688 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4689 data_offset
+= type_size(t
, &align
);
4690 /* put it as pointer */
4691 vpush_ref(t
& ~VT_ARRAY
, data_section
, fc
);
4692 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4698 if (parse_btype(&t
, &ad
)) {
4699 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4701 /* check ISOC99 compound literal */
4703 /* data is allocated locally by default */
4708 /* all except arrays are lvalues */
4709 if (!(ft
& VT_ARRAY
))
4710 r
|= lvalue_type(ft
);
4711 memset(&ad
, 0, sizeof(AttributeDef
));
4712 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4721 } else if (t
== '*') {
4724 } else if (t
== '&') {
4726 /* functions names must be treated as function pointers,
4727 except for unary '&' and sizeof. Since we consider that
4728 functions are not lvalues, we only have to handle it
4729 there and in function calls. */
4730 /* arrays can also be used although they are not lvalues */
4731 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4732 !(vtop
->t
& VT_ARRAY
))
4734 vtop
->t
= mk_pointer(vtop
->t
);
4739 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4740 vtop
->c
.i
= !vtop
->c
.i
;
4741 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4742 vtop
->c
.i
= vtop
->c
.i
^ 1;
4744 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4754 if (t
== TOK_SIZEOF
) {
4757 if (parse_btype(&t
, &ad
)) {
4758 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4760 /* XXX: some code could be generated: add eval
4772 vpushi(type_size(t
, &t
));
4774 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4777 } else if (t
== '-') {
4784 expect("identifier");
4788 error("'%s' undeclared", get_tok_str(t
, NULL
));
4789 /* for simple function calls, we tolerate undeclared
4790 external reference to int() function */
4791 s
= external_sym(t
, func_old_type
, 0);
4793 vset(s
->t
, s
->r
, s
->c
);
4794 /* if forward reference, we must point to s */
4795 if (vtop
->r
& VT_SYM
)
4800 /* post operations */
4802 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4805 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4807 if (tok
== TOK_ARROW
)
4812 /* expect pointer on structure */
4813 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4814 expect("struct or union");
4815 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4818 while ((s
= s
->next
) != NULL
) {
4823 error("field not found");
4824 /* add field offset to pointer */
4825 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4828 /* change type to field type, and set to lvalue */
4830 /* an array is never an lvalue */
4831 if (!(vtop
->t
& VT_ARRAY
))
4832 vtop
->r
|= lvalue_type(vtop
->t
);
4834 } else if (tok
== '[') {
4840 } else if (tok
== '(') {
4845 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4846 /* pointer test (no array accepted) */
4847 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4848 vtop
->t
= pointed_type(vtop
->t
);
4849 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4853 expect("function pointer");
4856 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4858 /* get return type */
4859 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4860 save_regs(0); /* save used temporary registers */
4861 gfunc_start(&gf
, s
->r
);
4863 sa
= s
->next
; /* first parameter */
4864 #ifdef INVERT_FUNC_PARAMS
4868 ParseState saved_parse_state
;
4871 /* read each argument and store it on a stack */
4872 /* XXX: merge it with macro args ? */
4878 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4882 else if (tok
== ')')
4884 tok_str_add_tok(&str
);
4887 tok_str_add(&str
, -1); /* end of file added */
4888 tok_str_add(&str
, 0);
4889 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4890 s1
->next
= sa
; /* add reference to argument */
4899 /* now generate code in reverse order by reading the stack */
4900 save_parse_state(&saved_parse_state
);
4902 macro_ptr
= (int *)args
->c
;
4906 expect("',' or ')'");
4907 gfunc_param_typed(&gf
, s
, args
->next
);
4909 free((int *)args
->c
);
4913 restore_parse_state(&saved_parse_state
);
4916 /* compute first implicit argument if a structure is returned */
4917 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4918 /* get some space for the returned structure */
4919 size
= type_size(s
->t
, &align
);
4920 loc
= (loc
- size
) & -align
;
4922 ret
.r
= VT_LOCAL
| VT_LVAL
;
4923 /* pass it as 'int' to avoid structure arg passing
4925 vset(VT_INT
, VT_LOCAL
, loc
);
4931 /* return in register */
4932 if (is_float(ret
.t
)) {
4935 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4941 #ifndef INVERT_FUNC_PARAMS
4945 gfunc_param_typed(&gf
, s
, sa
);
4955 error("too few arguments to function");
4959 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4973 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4974 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4975 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4998 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4999 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5000 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5001 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5002 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5003 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5004 (l
== 5 && tok
== '&') ||
5005 (l
== 6 && tok
== '^') ||
5006 (l
== 7 && tok
== '|') ||
5007 (l
== 8 && tok
== TOK_LAND
) ||
5008 (l
== 9 && tok
== TOK_LOR
)) {
5017 /* only used if non constant */
5025 if (tok
!= TOK_LAND
) {
5028 vset(VT_INT
, VT_JMPI
, t
);
5045 if (tok
!= TOK_LOR
) {
5048 vset(VT_INT
, VT_JMP
, t
);
5058 /* XXX: better constant handling */
5061 int t
, u
, c
, r1
, r2
, rc
;
5081 save_regs(1); /* we need to save all registers here except
5082 at the top because it is a branch point */
5085 /* XXX: long long handling ? */
5087 if (is_float(vtop
->t
))
5090 vtop
--; /* no vpop so that FP stack is not flushed */
5115 /* parse a constant expression and return value in vtop */
5116 void expr_const1(void)
5122 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5127 /* parse an integer constant and return its value */
5128 int expr_const(void)
5137 /* return the label token if current token is a label, otherwise
5144 /* fast test first */
5145 if (tok
< TOK_UIDENT
)
5147 /* no need to save tokc since we expect an identifier */
5155 /* XXX: may not work in all cases (macros ?) */
5164 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5169 /* generate line number info */
5171 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5172 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5174 last_line_num
= file
->line_num
;
5177 if (tok
== TOK_IF
) {
5184 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5186 if (c
== TOK_ELSE
) {
5190 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5191 gsym(d
); /* patch else jmp */
5194 } else if (tok
== TOK_WHILE
) {
5202 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5206 } else if (tok
== '{') {
5209 s
= local_stack
.top
;
5210 while (tok
!= '}') {
5213 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5215 /* pop locally defined symbols */
5216 sym_pop(&local_stack
, s
);
5218 } else if (tok
== TOK_RETURN
) {
5222 gen_assign_cast(func_vt
);
5223 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5224 /* if returning structure, must copy it to implicit
5225 first pointer arg location */
5226 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5229 /* copy structure value to pointer */
5231 } else if (is_float(func_vt
)) {
5236 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5239 rsym
= gjmp(rsym
); /* jmp */
5240 } else if (tok
== TOK_BREAK
) {
5243 error("cannot break");
5244 *bsym
= gjmp(*bsym
);
5247 } else if (tok
== TOK_CONTINUE
) {
5250 error("cannot continue");
5251 *csym
= gjmp(*csym
);
5254 } else if (tok
== TOK_FOR
) {
5281 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5286 if (tok
== TOK_DO
) {
5291 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5302 if (tok
== TOK_SWITCH
) {
5306 /* XXX: other types than integer */
5307 case_reg
= gv(RC_INT
);
5311 b
= gjmp(0); /* jump to first case */
5313 block(&a
, csym
, &b
, &c
, case_reg
);
5314 /* if no default, jmp after switch */
5322 if (tok
== TOK_CASE
) {
5329 if (gnu_ext
&& tok
== TOK_DOTS
) {
5333 warning("empty case range");
5335 /* since a case is like a label, we must skip it with a jmp */
5338 vset(VT_INT
, case_reg
, 0);
5342 *case_sym
= gtst(1, 0);
5345 *case_sym
= gtst(1, 0);
5346 vset(VT_INT
, case_reg
, 0);
5349 *case_sym
= gtst(1, *case_sym
);
5353 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5355 if (tok
== TOK_DEFAULT
) {
5361 error("too many 'default'");
5363 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5365 if (tok
== TOK_GOTO
) {
5367 s
= sym_find1(&label_stack
, tok
);
5368 /* put forward definition if needed */
5370 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5371 /* label already defined */
5372 if (s
->t
& LABEL_FORWARD
)
5382 s
= sym_find1(&label_stack
, b
);
5384 if (!(s
->t
& LABEL_FORWARD
))
5385 error("multiple defined label");
5390 sym_push1(&label_stack
, b
, 0, ind
);
5392 /* we accept this, but it is a mistake */
5394 warning("deprecated use of label at end of compound statement");
5396 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5398 /* expression case */
5408 /* t is the array or struct type. c is the array or struct
5409 address. cur_index/cur_field is the pointer to the current
5410 value. 'size_only' is true if only size info is needed (only used
5412 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5413 int *cur_index
, Sym
**cur_field
,
5417 int notfirst
, index
, align
, l
;
5420 if (gnu_ext
&& (l
= is_label()) != 0)
5423 while (tok
== '[' || tok
== '.') {
5425 if (!(t
& VT_ARRAY
))
5426 expect("array type");
5427 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5429 index
= expr_const();
5430 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5431 expect("invalid index");
5435 t
= pointed_type(t
);
5436 c
+= index
* type_size(t
, &align
);
5442 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5443 expect("struct/union type");
5444 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5456 t
= f
->t
| (t
& ~VT_TYPE
);
5471 t
= pointed_type(t
);
5472 c
+= index
* type_size(t
, &align
);
5476 error("too many field init");
5477 t
= f
->t
| (t
& ~VT_TYPE
);
5481 decl_initializer(t
, sec
, c
, 0, size_only
);
5485 #define EXPR_CONST 1
5488 /* store a value or an expression directly in global data or in local array */
5489 void init_putv(int t
, Section
*sec
, unsigned long c
,
5490 int v
, int expr_type
)
5492 int saved_global_expr
, bt
;
5500 /* compound literals must be allocated globally in this case */
5501 saved_global_expr
= global_expr
;
5504 global_expr
= saved_global_expr
;
5512 /* XXX: not portable */
5513 /* XXX: generate error if incorrect relocation */
5516 ptr
= sec
->data
+ c
;
5517 if ((vtop
->r
& VT_SYM
) &&
5523 error("initializer element is not computable at load time");
5526 *(char *)ptr
= vtop
->c
.i
;
5529 *(short *)ptr
= vtop
->c
.i
;
5532 *(double *)ptr
= vtop
->c
.d
;
5535 *(long double *)ptr
= vtop
->c
.ld
;
5538 *(long long *)ptr
= vtop
->c
.ll
;
5541 if (vtop
->r
& VT_SYM
) {
5542 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5545 *(int *)ptr
= vtop
->c
.i
;
5551 vset(t
, VT_LOCAL
, c
);
5558 /* put zeros for variable based init */
5559 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5564 /* nothing to do because globals are already set to zero */
5566 gfunc_start(&gf
, FUNC_CDECL
);
5571 vset(VT_INT
, VT_LOCAL
, c
);
5573 vpush_sym(func_old_type
, TOK_memset
);
5578 /* 't' contains the type and storage info. 'c' is the offset of the
5579 object in section 'sec'. If 'sec' is NULL, it means stack based
5580 allocation. 'first' is true if array '{' must be read (multi
5581 dimension implicit array init handling). 'size_only' is true if
5582 size only evaluation is wanted (only for arrays). */
5583 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5585 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5586 int t1
, size1
, align1
, expr_type
;
5591 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5594 t1
= pointed_type(t
);
5595 size1
= type_size(t1
, &align1
);
5598 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5604 /* only parse strings here if correct type (otherwise: handle
5605 them as ((w)char *) expressions */
5606 if ((tok
== TOK_LSTR
&&
5607 (t1
& VT_BTYPE
) == VT_INT
) ||
5609 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5610 /* XXX: move multiple string parsing in parser ? */
5611 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5613 /* compute maximum number of chars wanted */
5615 if (n
>= 0 && nb
> (n
- array_length
))
5616 nb
= n
- array_length
;
5619 warning("initializer-string for array is too long");
5621 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5622 ts
->str
[i
], EXPR_VAL
);
5628 /* only add trailing zero if enough storage (no
5629 warning in this case since it is standard) */
5630 if (n
< 0 || array_length
< n
) {
5632 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5638 while (tok
!= '}') {
5639 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5640 if (n
>= 0 && index
>= n
)
5641 error("index too large");
5642 /* must put zero in holes (note that doing it that way
5643 ensures that it even works with designators) */
5644 if (!size_only
&& array_length
< index
) {
5645 init_putz(t1
, sec
, c
+ array_length
* size1
,
5646 (index
- array_length
) * size1
);
5649 if (index
> array_length
)
5650 array_length
= index
;
5651 /* special test for multi dimensional arrays (may not
5652 be strictly correct if designators are used at the
5654 if (index
>= n
&& no_oblock
)
5663 /* put zeros at the end */
5664 if (!size_only
&& n
>= 0 && array_length
< n
) {
5665 init_putz(t1
, sec
, c
+ array_length
* size1
,
5666 (n
- array_length
) * size1
);
5668 /* patch type size if needed */
5670 s
->c
= array_length
;
5671 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5672 /* XXX: union needs only one init */
5674 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5679 while (tok
!= '}') {
5680 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5681 /* fill with zero between fields */
5683 if (!size_only
&& array_length
< index
) {
5684 init_putz(t
, sec
, c
+ array_length
,
5685 index
- array_length
);
5687 index
= index
+ type_size(f
->t
, &align1
);
5688 if (index
> array_length
)
5689 array_length
= index
;
5695 /* put zeros at the end */
5696 if (!size_only
&& array_length
< n
) {
5697 init_putz(t
, sec
, c
+ array_length
,
5701 } else if (tok
== '{') {
5703 decl_initializer(t
, sec
, c
, first
, size_only
);
5705 } else if (size_only
) {
5706 /* just skip expression */
5708 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5712 else if (tok
== ')')
5717 /* currently, we always use constant expression for globals
5718 (may change for scripting case) */
5719 expr_type
= EXPR_CONST
;
5721 expr_type
= EXPR_ANY
;
5722 init_putv(t
, sec
, c
, 0, expr_type
);
5726 /* parse an initializer for type 't' if 'has_init' is true, and
5727 allocate space in local or global data space ('r' is either
5728 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5729 variable 'v' of scope 'scope' is declared before initializers are
5730 parsed. If 'v' is zero, then a reference to the new object is put
5731 in the value stack. */
5732 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5735 int size
, align
, addr
, data_offset
;
5737 ParseState saved_parse_state
;
5738 TokenString init_str
;
5741 size
= type_size(t
, &align
);
5742 /* If unknown size, we must evaluate it before
5743 evaluating initializers because
5744 initializers can generate global data too
5745 (e.g. string pointers or ISOC99 compound
5746 literals). It also simplifies local
5747 initializers handling */
5748 tok_str_new(&init_str
);
5751 error("unknown type size");
5752 /* get all init string */
5754 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5756 error("unexpected end of file in initializer");
5757 tok_str_add_tok(&init_str
);
5760 else if (tok
== '}') {
5767 tok_str_add(&init_str
, -1);
5768 tok_str_add(&init_str
, 0);
5771 save_parse_state(&saved_parse_state
);
5773 macro_ptr
= init_str
.str
;
5775 decl_initializer(t
, NULL
, 0, 1, 1);
5776 /* prepare second initializer parsing */
5777 macro_ptr
= init_str
.str
;
5780 /* if still unknown size, error */
5781 size
= type_size(t
, &align
);
5783 error("unknown type size");
5785 /* take into account specified alignment if bigger */
5786 if (ad
->aligned
> align
)
5787 align
= ad
->aligned
;
5788 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5790 if (do_bounds_check
&& (t
& VT_ARRAY
))
5792 #ifdef TCC_TARGET_IL
5793 /* XXX: ugly patch to allocate local variables for IL, just
5798 loc
= (loc
- size
) & -align
;
5801 /* handles bounds */
5802 /* XXX: currently, since we do only one pass, we cannot track
5803 '&' operators, so we add only arrays */
5804 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5806 /* add padding between regions */
5808 /* then add local bound info */
5809 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5810 *bounds_ptr
++ = addr
;
5811 *bounds_ptr
++ = size
;
5812 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5815 /* compute section */
5823 data_offset
= sec
->data_ptr
- sec
->data
;
5824 data_offset
= (data_offset
+ align
- 1) & -align
;
5826 /* very important to increment global pointer at this time
5827 because initializers themselves can create new initializers */
5828 data_offset
+= size
;
5829 /* handles bounds */
5830 if (do_bounds_check
) {
5832 /* first, we need to add at least one byte between each region */
5834 /* then add global bound info */
5835 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5836 /* XXX: add relocation */
5837 *bounds_ptr
++ = addr
+ (unsigned long)sec
->data
;
5838 *bounds_ptr
++ = size
;
5839 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5841 sec
->data_ptr
= sec
->data
+ data_offset
;
5847 /* local variable */
5848 sym_push(v
, t
, r
, addr
);
5850 if (scope
== VT_CONST
) {
5851 /* global scope: see if already defined */
5855 if (!is_compatible_types(sym
->t
, t
))
5856 error("incompatible types for redefinition of '%s'",
5857 get_tok_str(v
, NULL
));
5858 if (!(sym
->t
& VT_EXTERN
))
5859 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5860 sym
->t
&= ~VT_EXTERN
;
5863 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5865 put_extern_sym(sym
, sec
, addr
);
5869 /* push local reference */
5872 /* push global reference */
5873 vpush_ref(t
, sec
, addr
);
5877 decl_initializer(t
, sec
, addr
, 1, 0);
5878 /* restore parse state if needed */
5881 restore_parse_state(&saved_parse_state
);
5886 void put_func_debug(int t
)
5891 /* XXX: we put here a dummy type */
5892 snprintf(buf
, sizeof(buf
), "%s:%c1",
5893 funcname
, t
& VT_STATIC
? 'f' : 'F');
5894 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5900 /* not finished : try to put some local vars in registers */
5901 //#define CONFIG_REG_VARS
5903 #ifdef CONFIG_REG_VARS
5904 void add_var_ref(int t
)
5906 printf("%s:%d: &%s\n",
5907 file
->filename
, file
->line_num
,
5908 get_tok_str(t
, NULL
));
5911 /* first pass on a function with heuristic to extract variable usage
5912 and pointer references to local variables for register allocation */
5913 void analyse_function(void)
5920 /* any symbol coming after '&' is considered as being a
5921 variable whose reference is taken. It is highly unaccurate
5922 but it is difficult to do better without a complete parse */
5925 /* if '& number', then no need to examine next tokens */
5926 if (tok
== TOK_CINT
||
5928 tok
== TOK_CLLONG
||
5929 tok
== TOK_CULLONG
) {
5931 } else if (tok
>= TOK_UIDENT
) {
5932 /* if '& ident [' or '& ident ->', then ident address
5936 if (tok
!= '[' && tok
!= TOK_ARROW
)
5940 while (tok
!= '}' && tok
!= ';' &&
5941 !((tok
== ',' || tok
== ')') && level
== 0)) {
5942 if (tok
>= TOK_UIDENT
) {
5944 } else if (tok
== '(') {
5946 } else if (tok
== ')') {
5959 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5962 int t
, b
, v
, has_init
, r
;
5967 if (!parse_btype(&b
, &ad
)) {
5968 /* skip redundant ';' */
5969 /* XXX: find more elegant solution */
5974 /* special test for old K&R protos without explicit int
5975 type. Only accepted when defining global data */
5976 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5980 if (((b
& VT_BTYPE
) == VT_ENUM
||
5981 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5983 /* we accept no variable after */
5987 while (1) { /* iterate thru each declaration */
5988 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
5992 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5993 printf("type = '%s'\n", buf
);
5997 #ifdef CONFIG_REG_VARS
5998 TokenString func_str
;
5999 ParseState saved_parse_state
;
6004 error("cannot use local functions");
6006 expect("function definition");
6008 #ifdef CONFIG_REG_VARS
6009 /* parse all function code and record it */
6011 tok_str_new(&func_str
);
6017 error("unexpected end of file");
6018 tok_str_add_tok(&func_str
);
6023 } else if (t
== '}') {
6025 if (block_level
== 0)
6029 tok_str_add(&func_str
, -1);
6030 tok_str_add(&func_str
, 0);
6032 save_parse_state(&saved_parse_state
);
6034 macro_ptr
= func_str
.str
;
6039 /* compute text section */
6040 cur_text_section
= ad
.section
;
6041 if (!cur_text_section
)
6042 cur_text_section
= text_section
;
6043 ind
= (int)cur_text_section
->data_ptr
;
6044 funcname
= get_tok_str(v
, NULL
);
6047 /* if symbol is already defined, then put complete type */
6050 /* put function symbol */
6051 sym
= sym_push1(&global_stack
, v
, t
, 0);
6053 put_extern_sym(sym
, cur_text_section
,
6054 ind
- (int)cur_text_section
->data
);
6055 sym
->r
= VT_SYM
| VT_CONST
;
6056 /* put debug symbol */
6059 /* push a dummy symbol to enable local sym storage */
6060 sym_push1(&local_stack
, 0, 0, 0);
6064 #ifdef CONFIG_REG_VARS
6065 macro_ptr
= func_str
.str
;
6068 block(NULL
, NULL
, NULL
, NULL
, 0);
6071 cur_text_section
->data_ptr
= (unsigned char *)ind
;
6072 sym_pop(&label_stack
, NULL
); /* reset label stack */
6073 sym_pop(&local_stack
, NULL
); /* reset local stack */
6074 /* end of function */
6076 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6078 funcname
= ""; /* for safety */
6079 func_vt
= VT_VOID
; /* for safety */
6080 ind
= 0; /* for safety */
6082 #ifdef CONFIG_REG_VARS
6084 restore_parse_state(&saved_parse_state
);
6088 if (b
& VT_TYPEDEF
) {
6089 /* save typedefed type */
6090 /* XXX: test storage specifiers ? */
6091 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6092 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6093 /* external function definition */
6094 external_sym(v
, t
, 0);
6096 /* not lvalue if array */
6098 if (!(t
& VT_ARRAY
))
6099 r
|= lvalue_type(t
);
6100 if (b
& VT_EXTERN
) {
6101 /* external variable */
6102 external_sym(v
, t
, r
);
6108 has_init
= (tok
== '=');
6111 decl_initializer_alloc(t
, &ad
, r
,
6125 /* compile the C file opened in 'file'. Return non zero if errors. */
6126 static int tcc_compile(TCCState
*s
)
6133 include_stack_ptr
= include_stack
;
6134 ifdef_stack_ptr
= ifdef_stack
;
6137 anon_sym
= SYM_FIRST_ANOM
;
6139 /* file info: full path + filename */
6141 getcwd(buf
, sizeof(buf
));
6142 pstrcat(buf
, sizeof(buf
), "/");
6143 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6144 put_stabs(file
->filename
, N_SO
, 0, 0,
6145 (unsigned long)text_section
->data_ptr
);
6147 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6148 symbols can be safely used */
6149 put_elf_sym(symtab_section
, 0, 0,
6150 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6151 SHN_ABS
, file
->filename
);
6153 /* define common 'char *' type because it is often used internally
6154 for arrays and struct dereference */
6155 char_pointer_type
= mk_pointer(VT_BYTE
);
6156 /* define an old type function 'int func()' */
6158 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
6159 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6161 define_start
= define_stack
.top
;
6163 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6167 expect("declaration");
6169 /* end of translation unit info */
6171 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6174 /* reset define stack, but leave -Dsymbols (may be incorrect if
6175 they are undefined) */
6176 sym_pop(&define_stack
, define_start
);
6178 sym_pop(&global_stack
, NULL
);
6183 int tcc_compile_string(TCCState
*s
, const char *str
)
6185 BufferedFile bf1
, *bf
= &bf1
;
6188 /* init file structure */
6190 bf
->buf_ptr
= (char *)str
;
6191 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6192 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6196 ret
= tcc_compile(s
);
6198 /* currently, no need to close */
6202 /* define a symbol. A value can also be provided with the '=' operator */
6203 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6205 BufferedFile bf1
, *bf
= &bf1
;
6207 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6208 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6212 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6214 /* init file structure */
6216 bf
->buf_ptr
= bf
->buffer
;
6217 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6218 bf
->filename
[0] = '\0';
6222 include_stack_ptr
= include_stack
;
6224 /* parse with define parser */
6226 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6232 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6236 ts
= tok_alloc(sym
, 0);
6237 s
= sym_find1(&define_stack
, tok
);
6238 /* undefine symbol by putting an invalid name */
6240 sym_undef(&define_stack
, s
);
6243 static int put_elf_str(Section
*s
, const char *sym
)
6246 offset
= s
->data_ptr
- s
->data
;
6256 /* elf symbol hashing function */
6257 static unsigned long elf_hash(const unsigned char *name
)
6259 unsigned long h
= 0, g
;
6262 h
= (h
<< 4) + *name
++;
6271 /* return the symbol number */
6272 static int put_elf_sym(Section
*s
,
6273 unsigned long value
, unsigned long size
,
6274 int info
, int other
, int shndx
, const char *name
)
6276 int name_offset
, sym_index
;
6281 sym
= (Elf32_Sym
*)s
->data_ptr
;
6283 name_offset
= put_elf_str(s
->link
, name
);
6286 /* XXX: endianness */
6287 sym
->st_name
= name_offset
;
6288 sym
->st_value
= value
;
6289 sym
->st_size
= size
;
6290 sym
->st_info
= info
;
6291 sym
->st_other
= other
;
6292 sym
->st_shndx
= shndx
;
6293 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6296 /* only add global or weak symbols */
6297 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
6298 /* add another hashing entry */
6299 nbuckets
= ((int *)hs
->data
)[0];
6300 h
= elf_hash(name
) % nbuckets
;
6301 ((int *)hs
->data
)[2 + nbuckets
+ sym_index
] = ((int *)hs
->data
)[2 + h
];
6302 ((int *)hs
->data
)[2 + h
] = sym_index
;
6304 /* but still add room for all symbols */
6305 ((int *)hs
->data
)[1]++;
6306 hs
->data_ptr
+= sizeof(int);
6308 s
->data_ptr
+= sizeof(Elf32_Sym
);
6312 /* find global ELF symbol 'name' and return its index. Return 0 if not
6314 static int find_elf_sym(Section
*s
, const char *name
)
6318 int nbuckets
, sym_index
, h
;
6324 nbuckets
= ((int *)hs
->data
)[0];
6325 h
= elf_hash(name
) % nbuckets
;
6326 sym_index
= ((int *)hs
->data
)[2 + h
];
6327 while (sym_index
!= 0) {
6328 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6329 name1
= s
->link
->data
+ sym
->st_name
;
6330 if (!strcmp(name
, name1
))
6332 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6337 /* return elf symbol value or error */
6338 static unsigned long get_elf_sym_val(const char *name
)
6343 sym_index
= find_elf_sym(symtab_section
, name
);
6345 error("%s not defined", name
);
6346 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6347 return sym
->st_value
;
6350 /* add an elf symbol : check if it is already defined and patch
6351 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6352 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
6353 int info
, int sh_num
, const char *name
)
6356 int sym_bind
, sym_index
, sym_type
, esym_bind
;
6358 sym_bind
= ELF32_ST_BIND(info
);
6359 sym_type
= ELF32_ST_TYPE(info
);
6361 if (sym_bind
!= STB_LOCAL
) {
6362 /* we search global or weak symbols */
6363 sym_index
= find_elf_sym(s
, name
);
6366 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6367 if (esym
->st_shndx
!= SHN_UNDEF
) {
6368 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
6369 if (sh_num
== SHN_UNDEF
) {
6370 /* ignore adding of undefined symbol if the
6371 corresponding symbol is already defined */
6372 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
6373 /* global overrides weak, so patch */
6375 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
6376 /* weak is ignored if already global */
6379 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6380 sym_bind
, sh_num
, esym_bind
, esym
->st_shndx
);
6382 /* NOTE: we accept that two DLL define the same symbol */
6383 if (s
!= dynsymtab_section
)
6384 error("'%s' defined twice", name
);
6388 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6389 esym
->st_shndx
= sh_num
;
6390 esym
->st_value
= value
;
6391 esym
->st_size
= size
;
6395 sym_index
= put_elf_sym(s
, value
, size
,
6396 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6402 /* update sym->c so that it points to an external symbol in section
6403 'section' with value 'value' */
6404 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
)
6406 int sym_type
, sym_bind
, sh_num
, info
;
6412 sh_num
= section
->sh_num
;
6416 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6417 sym_type
= STT_FUNC
;
6419 sym_type
= STT_OBJECT
;
6420 if (sym
->t
& VT_STATIC
)
6421 sym_bind
= STB_LOCAL
;
6423 sym_bind
= STB_GLOBAL
;
6425 name
= get_tok_str(sym
->v
, NULL
);
6426 #ifdef CONFIG_TCC_BCHECK
6427 if (do_bounds_check
) {
6428 /* if bound checking is activated, we change some function
6429 names by adding the "__bound" prefix */
6441 strcpy(buf
, "__bound_");
6448 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6449 sym
->c
= add_elf_sym(symtab_section
, value
, 0, info
, sh_num
, name
);
6451 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6452 esym
->st_value
= value
;
6453 esym
->st_shndx
= sh_num
;
6457 /* put relocation */
6458 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
6459 int type
, int symbol
)
6467 /* if no relocation section, create it */
6468 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6469 /* if the symtab is allocated, then we consider the relocation
6471 sr
= new_section(buf
, SHT_REL
, symtab
->sh_flags
);
6472 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6474 sr
->sh_info
= s
->sh_num
;
6477 rel
= (Elf32_Rel
*)sr
->data_ptr
;
6478 /* XXX: endianness */
6479 rel
->r_offset
= offset
;
6480 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6481 sr
->data_ptr
+= sizeof(Elf32_Rel
);
6484 /* put stab debug information */
6487 unsigned long n_strx
; /* index into string table of name */
6488 unsigned char n_type
; /* type of symbol */
6489 unsigned char n_other
; /* misc info (usually empty) */
6490 unsigned short n_desc
; /* description field */
6491 unsigned long n_value
; /* value of symbol */
6494 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
6498 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
6500 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6505 sym
->n_other
= other
;
6507 sym
->n_value
= value
;
6509 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
6512 static void put_stabn(int type
, int other
, int desc
, int value
)
6514 put_stabs(NULL
, type
, other
, desc
, value
);
6517 static void put_stabd(int type
, int other
, int desc
)
6519 put_stabs(NULL
, type
, other
, desc
, 0);
6522 /* In an ELF file symbol table, the local symbols must appear below
6523 the global and weak ones. Since TCC cannot sort it while generating
6524 the code, we must do it after. All the relocation tables are also
6525 modified to take into account the symbol table sorting */
6526 static void sort_syms(Section
*s
)
6528 int *old_to_new_syms
;
6529 Elf32_Sym
*new_syms
;
6534 int type
, sym_index
;
6536 nb_syms
= (s
->data_ptr
- s
->data
) / sizeof(Elf32_Sym
);
6537 new_syms
= malloc(nb_syms
* sizeof(Elf32_Sym
));
6539 error("memory full");
6540 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
6541 if (!old_to_new_syms
)
6542 error("memory full");
6543 /* first pass for local symbols */
6544 p
= (Elf32_Sym
*)s
->data
;
6546 for(i
= 0; i
< nb_syms
; i
++) {
6547 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
6548 old_to_new_syms
[i
] = q
- new_syms
;
6553 /* save the number of local symbols in section header */
6554 s
->sh_info
= q
- new_syms
;
6556 /* then second pass for non local symbols */
6557 p
= (Elf32_Sym
*)s
->data
;
6558 for(i
= 0; i
< nb_syms
; i
++) {
6559 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
6560 old_to_new_syms
[i
] = q
- new_syms
;
6566 /* we copy the new symbols to the old */
6567 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
6570 /* now we modify all the relocations */
6571 for(i
= 1; i
< nb_sections
; i
++) {
6573 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
6574 for(rel
= (Elf32_Rel
*)sr
->data
;
6575 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6577 sym_index
= ELF32_R_SYM(rel
->r_info
);
6578 type
= ELF32_R_TYPE(rel
->r_info
);
6579 sym_index
= old_to_new_syms
[sym_index
];
6580 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
6585 free(old_to_new_syms
);
6588 /* relocate common symbols in the .bss section */
6589 static void relocate_common_syms(void)
6592 unsigned long offset
, align
;
6594 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6595 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6597 if (sym
->st_shndx
== SHN_COMMON
) {
6599 align
= sym
->st_value
;
6600 offset
= bss_section
->data_ptr
- bss_section
->data
;
6601 offset
= (offset
+ align
- 1) & -align
;
6602 sym
->st_value
= offset
;
6603 sym
->st_shndx
= bss_section
->sh_num
;
6604 offset
+= sym
->st_size
;
6605 bss_section
->data_ptr
= bss_section
->data
+ offset
;
6610 static void *resolve_sym(const char *sym
)
6612 return dlsym(NULL
, sym
);
6615 /* relocate symbol table, resolve undefined symbols if do_resolve is
6616 true and output error if undefined symbol. */
6617 static void relocate_syms(int do_resolve
)
6619 Elf32_Sym
*sym
, *esym
;
6620 int sym_bind
, sh_num
, sym_index
;
6624 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6625 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6627 sh_num
= sym
->st_shndx
;
6628 if (sh_num
== SHN_UNDEF
) {
6629 name
= strtab_section
->data
+ sym
->st_name
;
6631 name
= symtab_section
->link
->data
+ sym
->st_name
;
6632 addr
= (unsigned long)resolve_sym(name
);
6634 sym
->st_value
= addr
;
6637 } else if (dynsym
) {
6638 /* if dynamic symbol exist, then use it */
6639 sym_index
= find_elf_sym(dynsym
, name
);
6641 esym
= &((Elf32_Sym
*)dynsym
->data
)[sym_index
];
6642 sym
->st_value
= esym
->st_value
;
6646 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
6648 if (!strcmp(name
, "_fp_hw"))
6650 /* only weak symbols are accepted to be undefined. Their
6652 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
6653 if (sym_bind
== STB_WEAK
) {
6656 error("undefined symbol '%s'", name
);
6658 } else if (sh_num
< SHN_LORESERVE
) {
6659 /* add section base */
6660 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
6666 /* elf relocation, CPU dependant */
6667 static void elf_reloc(unsigned char *ptr
,
6668 unsigned long addr
, unsigned long val
, int type
,
6677 *(int *)ptr
+= val
- addr
;
6679 case R_386_GLOB_DAT
:
6680 case R_386_JMP_SLOT
:
6684 *(int *)ptr
+= got
->sh_addr
- addr
;
6687 *(int *)ptr
+= val
- got
->sh_addr
;
6690 /* we load the got offset */
6691 *(int *)ptr
+= got_offsets
[sym_index
];
6697 /* relocate a given section */
6698 static void relocate_section(Section
*s
)
6703 int type
, sym_index
;
6708 for(rel
= (Elf32_Rel
*)sr
->data
;
6709 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6711 ptr
= s
->data
+ rel
->r_offset
;
6713 sym_index
= ELF32_R_SYM(rel
->r_info
);
6714 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6715 val
= sym
->st_value
;
6716 type
= ELF32_R_TYPE(rel
->r_info
);
6717 elf_reloc(ptr
, s
->sh_addr
+ rel
->r_offset
, val
, type
, sym_index
);
6721 /* relocate relocation table in 'sr' */
6722 static void relocate_rel(Section
*sr
)
6727 s
= sections
[sr
->sh_info
];
6728 for(rel
= (Elf32_Rel
*)sr
->data
;
6729 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6731 rel
->r_offset
+= s
->sh_addr
;
6735 static void put_got_offset(int index
, unsigned long val
)
6740 if (index
>= nb_got_offsets
) {
6741 /* find immediately bigger power of 2 and reallocate array */
6745 tab
= realloc(got_offsets
, n
* sizeof(unsigned long));
6747 error("memory full");
6749 memset(got_offsets
+ nb_got_offsets
, 0,
6750 (n
- nb_got_offsets
) * sizeof(unsigned long));
6753 got_offsets
[index
] = val
;
6756 /* XXX: suppress that */
6757 static void put32(unsigned char *p
, unsigned int val
)
6765 static void build_got(void)
6767 /* if no got, then create it */
6768 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6769 got
->sh_entsize
= 4;
6770 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
6771 got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
6772 /* keep space for _DYNAMIC pointer, if present */
6775 /* two dummy got entries */
6776 put32(got
->data_ptr
, 0);
6778 put32(got
->data_ptr
, 0);
6782 /* put a got entry corresponding to a symbol in symtab_section. 'size'
6783 and 'info' can be modifed if more precise info comes from the DLL */
6784 static void put_got_entry(int reloc_type
, unsigned long size
, int info
,
6790 unsigned long offset
;
6795 /* if a got entry already exists for that symbol, no need to add one */
6796 if (sym_index
< nb_got_offsets
&&
6797 got_offsets
[sym_index
] != 0)
6800 put_got_offset(sym_index
, got
->data_ptr
- got
->data
);
6803 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6804 name
= symtab_section
->link
->data
+ sym
->st_name
;
6805 offset
= sym
->st_value
;
6806 /* NOTE: we put temporarily the got offset */
6807 if (reloc_type
== R_386_JMP_SLOT
) {
6809 offset
= got
->data_ptr
- got
->data
;
6811 index
= put_elf_sym(dynsym
, offset
,
6812 size
, info
, 0, sym
->st_shndx
, name
);
6813 /* put a got entry */
6814 put_elf_reloc(dynsym
, got
,
6815 got
->data_ptr
- got
->data
,
6818 put32(got
->data_ptr
, 0);
6822 /* build GOT and PLT entries */
6823 static void build_got_entries(void)
6825 Section
*s
, *symtab
;
6828 int i
, type
, reloc_type
, sym_index
;
6830 for(i
= 1; i
< nb_sections
; i
++) {
6832 if (s
->sh_type
!= SHT_REL
)
6834 /* no need to handle got relocations */
6835 if (s
->link
!= symtab_section
)
6838 for(rel
= (Elf32_Rel
*)s
->data
;
6839 rel
< (Elf32_Rel
*)s
->data_ptr
;
6841 type
= ELF32_R_TYPE(rel
->r_info
);
6849 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
6850 sym_index
= ELF32_R_SYM(rel
->r_info
);
6851 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6852 /* look at the symbol got offset. If none, then add one */
6853 if (type
== R_386_GOT32
)
6854 reloc_type
= R_386_GLOB_DAT
;
6856 reloc_type
= R_386_JMP_SLOT
;
6857 put_got_entry(reloc_type
, sym
->st_size
, sym
->st_info
,
6868 static Section
*new_section_hash(const char *name
, int sh_flags
,
6869 int nb_buckets
, Section
*symtab
)
6872 hash
= new_section(name
, SHT_HASH
, sh_flags
);
6873 ((int *)hash
->data
)[0] = nb_buckets
;
6874 ((int *)hash
->data
)[1] = 1;
6875 hash
->sh_entsize
= sizeof(int);
6876 hash
->data_ptr
+= (2 + nb_buckets
+ 1) * sizeof(int);
6877 symtab
->hash
= hash
;
6878 hash
->link
= symtab
;
6882 /* put dynamic tag */
6883 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
6886 dyn
= (Elf32_Dyn
*)dynamic
->data_ptr
;
6888 dyn
->d_un
.d_val
= val
;
6889 dynamic
->data_ptr
+= sizeof(Elf32_Dyn
);
6892 /* add tcc runtime libraries */
6893 static void tcc_add_runtime(TCCState
*s1
)
6897 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.o");
6898 tcc_add_file(s1
, buf
);
6899 #ifdef CONFIG_TCC_BCHECK
6900 if (do_bounds_check
) {
6901 /* XXX: add an object file to do that */
6902 *(int *)bounds_section
->data_ptr
= 0;
6903 bounds_section
->data_ptr
+= sizeof(int);
6904 add_elf_sym(symtab_section
, 0, 0,
6905 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6906 bounds_section
->sh_num
, "__bounds_start");
6907 add_elf_sym(symtab_section
, (long)&rt_error
, 0,
6908 ELF32_ST_INFO(STB_GLOBAL
, STT_FUNC
),
6909 SHN_ABS
, "rt_error");
6910 /* add bound check code */
6911 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
6912 tcc_add_file(s1
, buf
);
6915 /* add libc if not memory output */
6916 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
6917 tcc_add_library(s1
, "c");
6918 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
6920 /* add various standard linker symbols */
6921 add_elf_sym(symtab_section
,
6922 text_section
->data_ptr
- text_section
->data
, 0,
6923 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6924 text_section
->sh_num
, "_etext");
6925 add_elf_sym(symtab_section
,
6926 data_section
->data_ptr
- data_section
->data
, 0,
6927 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6928 data_section
->sh_num
, "_edata");
6929 add_elf_sym(symtab_section
,
6930 bss_section
->data_ptr
- bss_section
->data
, 0,
6931 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
6932 bss_section
->sh_num
, "_end");
6935 /* add dynamic sections so that the executable is dynamically linked */
6936 static char elf_interp
[] = "/lib/ld-linux.so.2";
6938 #define ELF_START_ADDR 0x08048000
6939 #define ELF_PAGE_SIZE 0x1000
6941 /* output an ELF file */
6942 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6943 /* XXX: suppress unneeded sections */
6944 int tcc_output_file(TCCState
*s1
, const char *filename
)
6950 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
6952 Section
*strsec
, *s
;
6953 Elf32_Shdr shdr
, *sh
;
6954 Elf32_Phdr
*phdr
, *ph
;
6955 Section
*interp
, *plt
, *dynamic
, *dynstr
, *hash
;
6956 unsigned char *saved_dynamic_data_ptr
;
6958 int type
, file_type
;
6959 unsigned long rel_addr
, rel_size
;
6961 file_type
= s1
->output_type
;
6963 if (file_type
!= TCC_OUTPUT_OBJ
)
6964 tcc_add_runtime(s1
);
6971 plt
= NULL
; /* avoid warning */
6972 hash
= NULL
; /* avoid warning */
6973 dynstr
= NULL
; /* avoid warning */
6974 saved_dynamic_data_ptr
= NULL
; /* avoid warning */
6976 if (file_type
!= TCC_OUTPUT_OBJ
) {
6978 relocate_common_syms();
6982 int sym_index
, index
;
6985 if (file_type
== TCC_OUTPUT_EXE
) {
6986 /* add interpreter section only if executable */
6987 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
6988 interp
->sh_addralign
= 1;
6989 strcpy(interp
->data_ptr
, elf_interp
);
6990 interp
->data_ptr
+= sizeof(elf_interp
);
6993 /* add dynamic symbol table */
6994 dynsym
= new_section(".dynsym", SHT_DYNSYM
, SHF_ALLOC
);
6995 dynsym
->sh_entsize
= sizeof(Elf32_Sym
);
6996 dynstr
= new_section(".dynstr", SHT_STRTAB
, SHF_ALLOC
);
6997 put_elf_str(dynstr
, "");
6998 dynsym
->link
= dynstr
;
6999 put_elf_sym(dynsym
, 0, 0, 0, 0, 0, NULL
);
7002 hash
= new_section_hash(".hash", SHF_ALLOC
,
7003 ELF_DYNSYM_HASH_SIZE
, dynsym
);
7005 /* add dynamic section */
7006 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
7007 SHF_ALLOC
| SHF_WRITE
);
7008 dynamic
->link
= dynstr
;
7009 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
7012 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7013 plt
->sh_entsize
= 4;
7015 /* scan for undefined symbols and see if they are in the
7016 dynamic symbols. If a symbol STT_FUNC is found, then we
7017 add it in the PLT. If a symbol STT_OBJECT is found, we
7018 add it in the .bss section with a suitable relocation */
7019 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7020 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
7022 if (sym
->st_shndx
== SHN_UNDEF
) {
7023 name
= symtab_section
->link
->data
+ sym
->st_name
;
7024 sym_index
= find_elf_sym(dynsymtab_section
, name
);
7026 esym
= &((Elf32_Sym
*)dynsymtab_section
->data
)[sym_index
];
7027 type
= ELF32_ST_TYPE(esym
->st_info
);
7028 if (type
== STT_FUNC
) {
7029 put_got_entry(R_386_JMP_SLOT
, esym
->st_size
,
7031 sym
- (Elf32_Sym
*)symtab_section
->data
);
7032 } else if (type
== STT_OBJECT
) {
7033 unsigned long offset
;
7034 offset
= bss_section
->data_ptr
- bss_section
->data
;
7035 /* XXX: which alignment ? */
7036 offset
= (offset
+ 8 - 1) & -8;
7037 index
= put_elf_sym(dynsym
, offset
, esym
->st_size
,
7039 bss_section
->sh_num
, name
);
7040 put_elf_reloc(dynsym
, bss_section
,
7041 offset
, R_386_COPY
, index
);
7042 offset
+= esym
->st_size
;
7043 bss_section
->data_ptr
= bss_section
->data
+ offset
;
7046 /* STT_NOTYPE or STB_WEAK undefined symbols
7048 /* XXX: STT_NOTYPE is only used to exclude the
7049 unreferenced '_fp_hw' symbol. need a better
7051 if (ELF32_ST_TYPE(sym
->st_info
) == STT_NOTYPE
||
7052 ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
) {
7054 error("undefined symbol '%s'", name
);
7060 /* now look at unresolved dynamic symbols and export
7061 corresponding symbol */
7062 for(sym
= (Elf32_Sym
*)dynsymtab_section
->data
+ 1;
7063 sym
< (Elf32_Sym
*)dynsymtab_section
->data_ptr
;
7065 if (sym
->st_shndx
== SHN_UNDEF
) {
7066 name
= dynsymtab_section
->link
->data
+ sym
->st_name
;
7067 sym_index
= find_elf_sym(symtab_section
, name
);
7070 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
) {
7071 /* weak symbols can stay undefined */
7073 warning("undefined dynamic symbol '%s'", name
);
7079 build_got_entries();
7081 /* update PLT/GOT sizes so that we can allocate their space */
7082 plt
->data_ptr
+= 16 * (nb_plt_entries
+ 1);
7084 /* add a list of needed dlls */
7085 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7086 DLLReference
*dllref
= loaded_dlls
[i
];
7087 if (dllref
->level
== 0)
7088 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
7091 /* add necessary space for other entries */
7092 saved_dynamic_data_ptr
= dynamic
->data_ptr
;
7093 dynamic
->data_ptr
+= 8 * 9;
7095 /* still need to build got entries in case of static link */
7096 build_got_entries();
7100 memset(&ehdr
, 0, sizeof(ehdr
));
7102 /* we add a section for symbols */
7103 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
7104 put_elf_str(strsec
, "");
7106 /* compute number of sections */
7107 shnum
= nb_sections
;
7109 /* this array is used to reorder sections in the output file */
7110 section_order
= malloc(sizeof(int) * shnum
);
7112 error("memory full");
7113 section_order
[0] = 0;
7116 /* compute number of program headers */
7119 case TCC_OUTPUT_OBJ
:
7122 case TCC_OUTPUT_EXE
:
7128 case TCC_OUTPUT_DLL
:
7133 /* allocate strings for section names */
7134 for(i
= 1; i
< nb_sections
; i
++) {
7136 s
->sh_name
= put_elf_str(strsec
, s
->name
);
7137 s
->sh_size
= s
->data_ptr
- s
->data
;
7140 /* allocate program segment headers */
7141 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
7143 error("memory full");
7144 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
7146 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7148 /* compute section to program header mapping */
7149 if (file_type
== TCC_OUTPUT_DLL
)
7152 addr
= ELF_START_ADDR
;
7154 /* dynamic relocation table information, for .dynamic section */
7158 /* compute address after headers */
7159 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
7161 /* leave one program header for the program interpreter */
7166 for(j
= 0; j
< 2; j
++) {
7167 ph
->p_type
= PT_LOAD
;
7169 ph
->p_flags
= PF_R
| PF_X
;
7171 ph
->p_flags
= PF_R
| PF_W
;
7172 ph
->p_align
= ELF_PAGE_SIZE
;
7174 /* we do the following ordering: interp, symbol tables,
7175 relocations, progbits, nobits */
7176 /* XXX: do faster and simpler sorting */
7177 for(k
= 0; k
< 5; k
++) {
7178 for(i
= 1; i
< nb_sections
; i
++) {
7180 /* compute if section should be included */
7182 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7186 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7187 (SHF_ALLOC
| SHF_WRITE
))
7193 } else if (s
->sh_type
== SHT_DYNSYM
||
7194 s
->sh_type
== SHT_STRTAB
||
7195 s
->sh_type
== SHT_HASH
) {
7198 } else if (s
->sh_type
== SHT_REL
) {
7201 } else if (s
->sh_type
== SHT_NOBITS
) {
7208 section_order
[sh_order_index
++] = i
;
7210 /* section matches: we align it and add its size */
7212 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7213 ~(s
->sh_addralign
- 1);
7214 s
->sh_offset
= file_offset
;
7215 addr
+= file_offset
- tmp
;
7218 /* update program header infos */
7219 if (ph
->p_offset
== 0) {
7220 ph
->p_offset
= file_offset
;
7222 ph
->p_paddr
= ph
->p_vaddr
;
7224 /* update dynamic relocation infos */
7225 if (s
->sh_type
== SHT_REL
) {
7228 rel_size
+= s
->sh_size
;
7231 if (s
->sh_type
!= SHT_NOBITS
)
7232 file_offset
+= s
->sh_size
;
7235 ph
->p_filesz
= file_offset
- ph
->p_offset
;
7236 ph
->p_memsz
= addr
- ph
->p_vaddr
;
7240 /* if interpreter, then add corresponing program header */
7244 ph
->p_type
= PT_INTERP
;
7245 ph
->p_offset
= interp
->sh_offset
;
7246 ph
->p_vaddr
= interp
->sh_addr
;
7247 ph
->p_paddr
= ph
->p_vaddr
;
7248 ph
->p_filesz
= interp
->sh_size
;
7249 ph
->p_memsz
= interp
->sh_size
;
7251 ph
->p_align
= interp
->sh_addralign
;
7254 /* if dynamic section, then add corresponing program header */
7259 ph
= &phdr
[phnum
- 1];
7261 ph
->p_type
= PT_DYNAMIC
;
7262 ph
->p_offset
= dynamic
->sh_offset
;
7263 ph
->p_vaddr
= dynamic
->sh_addr
;
7264 ph
->p_paddr
= ph
->p_vaddr
;
7265 ph
->p_filesz
= dynamic
->sh_size
;
7266 ph
->p_memsz
= dynamic
->sh_size
;
7267 ph
->p_flags
= PF_R
| PF_W
;
7268 ph
->p_align
= dynamic
->sh_addralign
;
7270 /* put GOT dynamic section address */
7271 put32(got
->data
, dynamic
->sh_addr
);
7273 /* compute the PLT */
7274 plt
->data_ptr
= plt
->data
;
7276 /* first plt entry */
7278 p
[0] = 0xff; /* pushl got + 4 */
7280 put32(p
+ 2, got
->sh_addr
+ 4);
7281 p
[6] = 0xff; /* jmp *(got + 8) */
7283 put32(p
+ 8, got
->sh_addr
+ 8);
7284 plt
->data_ptr
+= 16;
7286 /* relocation symbols in .dynsym and build PLT. */
7288 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
7289 sym
< (Elf32_Sym
*)dynsym
->data_ptr
;
7291 type
= ELF32_ST_TYPE(sym
->st_info
);
7292 if (sym
->st_shndx
== SHN_UNDEF
) {
7293 if (type
== STT_FUNC
) {
7294 /* one more entry in PLT */
7296 p
[0] = 0xff; /* jmp *(got + x) */
7298 put32(p
+ 2, got
->sh_addr
+ sym
->st_value
);
7299 p
[6] = 0x68; /* push $xxx */
7300 put32(p
+ 7, plt_offset
);
7301 p
[11] = 0xe9; /* jmp plt_start */
7302 put32(p
+ 12, -(plt
->data_ptr
+ 16 - plt
->data
));
7304 /* patch symbol value to point to plt */
7305 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
7308 plt
->data_ptr
+= 16;
7310 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
7311 /* do symbol relocation */
7312 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
7315 /* put dynamic section entries */
7317 dynamic
->data_ptr
= saved_dynamic_data_ptr
;
7318 put_dt(dynamic
, DT_HASH
, hash
->sh_addr
);
7319 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
7320 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
7321 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_ptr
- dynstr
->data
);
7322 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
7323 put_dt(dynamic
, DT_REL
, rel_addr
);
7324 put_dt(dynamic
, DT_RELSZ
, rel_size
);
7325 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
7326 put_dt(dynamic
, DT_NULL
, 0);
7329 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
7330 ehdr
.e_phnum
= phnum
;
7331 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
7334 /* all other sections come after */
7335 for(i
= 1; i
< nb_sections
; i
++) {
7337 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
7339 section_order
[sh_order_index
++] = i
;
7341 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7342 ~(s
->sh_addralign
- 1);
7343 s
->sh_offset
= file_offset
;
7344 if (s
->sh_type
!= SHT_NOBITS
)
7345 file_offset
+= s
->sh_size
;
7348 /* if building executable or DLL, then relocate each section
7349 except the GOT which is already relocated */
7350 if (file_type
!= TCC_OUTPUT_OBJ
) {
7353 /* relocate sections */
7354 /* XXX: ignore sections with allocated relocations ? */
7355 for(i
= 1; i
< nb_sections
; i
++) {
7357 if ((s
->sh_flags
& SHF_ALLOC
)
7358 && s
->reloc
&& s
!= got
)
7359 relocate_section(s
);
7362 /* relocate relocation entries */
7363 for(i
= 1; i
< nb_sections
; i
++) {
7365 if ((s
->sh_flags
& SHF_ALLOC
) &&
7366 s
->sh_type
== SHT_REL
) {
7371 /* get entry point address */
7372 ehdr
.e_entry
= get_elf_sym_val("_start");
7375 sort_syms(symtab_section
);
7378 file_offset
= (file_offset
+ 3) & -4;
7381 ehdr
.e_ident
[0] = ELFMAG0
;
7382 ehdr
.e_ident
[1] = ELFMAG1
;
7383 ehdr
.e_ident
[2] = ELFMAG2
;
7384 ehdr
.e_ident
[3] = ELFMAG3
;
7385 ehdr
.e_ident
[4] = ELFCLASS32
;
7386 ehdr
.e_ident
[5] = ELFDATA2LSB
;
7387 ehdr
.e_ident
[6] = EV_CURRENT
;
7390 case TCC_OUTPUT_EXE
:
7391 ehdr
.e_type
= ET_EXEC
;
7393 case TCC_OUTPUT_DLL
:
7394 ehdr
.e_type
= ET_DYN
;
7396 case TCC_OUTPUT_OBJ
:
7397 ehdr
.e_type
= ET_REL
;
7400 ehdr
.e_machine
= EM_386
;
7401 ehdr
.e_version
= EV_CURRENT
;
7402 ehdr
.e_shoff
= file_offset
;
7403 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
7404 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
7405 ehdr
.e_shnum
= shnum
;
7406 ehdr
.e_shstrndx
= shnum
- 1;
7408 /* write elf file */
7409 if (file_type
== TCC_OUTPUT_OBJ
)
7413 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
7415 error("could not write '%s'", filename
);
7417 f
= fdopen(fd
, "w");
7418 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
7419 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
7420 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7421 for(i
=1;i
<nb_sections
;i
++) {
7422 s
= sections
[section_order
[i
]];
7423 if (s
->sh_type
!= SHT_NOBITS
) {
7424 while (offset
< s
->sh_offset
) {
7428 size
= s
->data_ptr
- s
->data
;
7429 fwrite(s
->data
, 1, size
, f
);
7433 while (offset
< ehdr
.e_shoff
) {
7438 /* output section headers */
7439 for(i
=0;i
<nb_sections
;i
++) {
7441 memset(sh
, 0, sizeof(Elf32_Shdr
));
7444 sh
->sh_name
= s
->sh_name
;
7445 sh
->sh_type
= s
->sh_type
;
7446 sh
->sh_flags
= s
->sh_flags
;
7447 sh
->sh_entsize
= s
->sh_entsize
;
7448 sh
->sh_info
= s
->sh_info
;
7450 sh
->sh_link
= s
->link
->sh_num
;
7451 sh
->sh_addralign
= s
->sh_addralign
;
7452 sh
->sh_addr
= s
->sh_addr
;
7453 sh
->sh_offset
= s
->sh_offset
;
7454 sh
->sh_size
= s
->sh_size
;
7456 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
7460 free(section_order
);
7465 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
7469 data
= malloc(size
);
7471 error("memory full");
7472 lseek(fd
, file_offset
, SEEK_SET
);
7473 read(fd
, data
, size
);
7477 typedef struct SectionMergeInfo
{
7478 Section
*s
; /* corresponding existing section */
7479 unsigned long offset
; /* offset of the new section in the existing section */
7480 int new_section
; /* true if section 's' was added */
7483 /* load an object file and merge it with current files */
7484 /* XXX: handle correctly stab (debug) info */
7485 static int tcc_load_object_file(TCCState
*s1
,
7486 int fd
, unsigned long file_offset
)
7489 Elf32_Shdr
*shdr
, *sh
;
7490 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
;
7491 unsigned char *strsec
, *strtab
;
7492 int *old_to_new_syms
;
7493 char *sh_name
, *name
;
7494 SectionMergeInfo
*sm_table
, *sm
;
7495 Elf32_Sym
*sym
, *symtab
;
7499 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
7501 if (ehdr
.e_ident
[0] != ELFMAG0
||
7502 ehdr
.e_ident
[1] != ELFMAG1
||
7503 ehdr
.e_ident
[2] != ELFMAG2
||
7504 ehdr
.e_ident
[3] != ELFMAG3
)
7506 /* test if object file */
7507 if (ehdr
.e_type
!= ET_REL
)
7509 /* test CPU specific stuff */
7510 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7511 ehdr
.e_machine
!= EM_386
) {
7513 error("invalid object file");
7516 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
7517 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7518 sm_table
= malloc(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7520 error("memory full");
7521 memset(sm_table
, 0, sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7523 /* load section names */
7524 sh
= &shdr
[ehdr
.e_shstrndx
];
7525 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7527 /* load symtab and strtab */
7531 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7533 if (sh
->sh_type
== SHT_SYMTAB
) {
7535 error("object must contain only one symtab");
7536 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7537 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7538 sm_table
[i
].s
= symtab_section
;
7540 /* now load strtab */
7541 sh
= &shdr
[sh
->sh_link
];
7542 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7546 /* now examine each section and try to merge its content with the
7548 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7549 /* no need to examine section name strtab */
7550 if (i
== ehdr
.e_shstrndx
)
7553 sh_name
= strsec
+ sh
->sh_name
;
7554 /* ignore sections types we do not handle */
7555 if (sh
->sh_type
!= SHT_PROGBITS
&&
7556 sh
->sh_type
!= SHT_REL
&&
7557 sh
->sh_type
!= SHT_NOBITS
)
7559 if (sh
->sh_addralign
< 1)
7560 sh
->sh_addralign
= 1;
7561 /* find corresponding section, if any */
7562 for(j
= 1; j
< nb_sections
;j
++) {
7564 if (!strcmp(s
->name
, sh_name
))
7567 /* not found: create new section */
7568 s
= new_section(sh_name
, sh
->sh_type
, sh
->sh_flags
);
7569 /* take as much info as possible from the section. sh_link and
7570 sh_info will be updated later */
7571 s
->sh_addralign
= sh
->sh_addralign
;
7572 s
->sh_entsize
= sh
->sh_entsize
;
7573 sm_table
[i
].new_section
= 1;
7575 if (sh
->sh_type
!= s
->sh_type
)
7578 /* align start of section */
7579 offset
= s
->data_ptr
- s
->data
;
7580 size
= sh
->sh_addralign
- 1;
7581 offset
= (offset
+ size
) & ~size
;
7582 if (sh
->sh_addralign
> s
->sh_addralign
)
7583 s
->sh_addralign
= sh
->sh_addralign
;
7584 s
->data_ptr
= s
->data
+ offset
;
7585 sm_table
[i
].offset
= offset
;
7587 /* concatenate sections */
7589 if (sh
->sh_type
!= SHT_NOBITS
) {
7590 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
7591 read(fd
, s
->data_ptr
, size
);
7593 s
->data_ptr
+= size
;
7596 /* second short pass to update sh_link and sh_info fields of new
7599 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7601 if (!s
|| !sm_table
[i
].new_section
)
7604 if (sh
->sh_link
> 0)
7605 s
->link
= sm_table
[sh
->sh_link
].s
;
7606 if (sh
->sh_type
== SHT_REL
) {
7607 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
7608 /* update backward link */
7609 sections
[s
->sh_info
]->reloc
= s
;
7613 /* resolve symbols */
7614 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
7615 if (!old_to_new_syms
)
7616 error("memory full");
7617 memset(old_to_new_syms
, 0, nb_syms
* sizeof(int));
7619 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
7620 if (sym
->st_shndx
!= SHN_UNDEF
&&
7621 sym
->st_shndx
< SHN_LORESERVE
) {
7622 sm
= &sm_table
[sym
->st_shndx
];
7623 /* if no corresponding section added, no need to add symbol */
7626 /* convert section number */
7627 sym
->st_shndx
= sm
->s
->sh_num
;
7629 sym
->st_value
+= sm
->offset
;
7632 name
= strtab
+ sym
->st_name
;
7633 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
7634 sym
->st_info
, sym
->st_shndx
, name
);
7635 old_to_new_syms
[i
] = sym_index
;
7638 /* third pass to patch relocation entries */
7639 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7644 offset
= sm_table
[i
].offset
;
7645 switch(s
->sh_type
) {
7647 /* take relocation offset information */
7648 offseti
= sm_table
[sh
->sh_info
].offset
;
7649 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
7650 rel
< (Elf32_Rel
*)s
->data_ptr
;
7654 /* convert symbol index */
7655 type
= ELF32_R_TYPE(rel
->r_info
);
7656 sym_index
= ELF32_R_SYM(rel
->r_info
);
7657 /* NOTE: only one symtab assumed */
7658 if (sym_index
>= nb_syms
)
7660 sym_index
= old_to_new_syms
[sym_index
];
7663 error("Invalid relocation entry");
7665 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
7666 /* offset the relocation offset */
7667 rel
->r_offset
+= offseti
;
7676 free(old_to_new_syms
);
7682 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7684 typedef struct ArchiveHeader
{
7685 char ar_name
[16]; /* name of this member */
7686 char ar_date
[12]; /* file mtime */
7687 char ar_uid
[6]; /* owner uid; printed as decimal */
7688 char ar_gid
[6]; /* owner gid; printed as decimal */
7689 char ar_mode
[8]; /* file mode, printed as octal */
7690 char ar_size
[10]; /* file size, printed as decimal */
7691 char ar_fmag
[2]; /* should contain ARFMAG */
7694 /* load a '.a' file */
7695 static int tcc_load_archive(TCCState
*s1
, int fd
)
7702 unsigned long file_offset
;
7704 /* skip magic which was already checked */
7705 read(fd
, magic
, sizeof(magic
));
7708 len
= read(fd
, &hdr
, sizeof(hdr
));
7711 if (len
!= sizeof(hdr
))
7712 error("invalid archive");
7713 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
7714 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
7715 size
= strtol(ar_size
, NULL
, 0);
7716 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
7717 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
7718 if (ar_name
[i
] != ' ')
7721 ar_name
[i
+ 1] = '\0';
7722 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7723 file_offset
= lseek(fd
, 0, SEEK_CUR
);
7724 if (!strcmp(ar_name
, "/") ||
7725 !strcmp(ar_name
, "//") ||
7726 !strcmp(ar_name
, "__.SYMDEF") ||
7727 !strcmp(ar_name
, "__.SYMDEF/") ||
7728 !strcmp(ar_name
, "ARFILENAMES/")) {
7729 /* skip symbol table or archive names */
7731 tcc_load_object_file(s1
, fd
, file_offset
);
7734 size
= (size
+ 1) & ~1;
7735 lseek(fd
, file_offset
+ size
, SEEK_SET
);
7740 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
7741 is referenced by the user (so it should be added as DT_NEEDED in
7742 the generated ELF file) */
7743 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
7746 Elf32_Shdr
*shdr
, *sh
, *sh1
;
7747 int i
, nb_syms
, nb_dts
, sym_bind
;
7748 Elf32_Sym
*sym
, *dynsym
;
7749 Elf32_Dyn
*dt
, *dynamic
;
7750 unsigned char *dynstr
;
7751 const char *name
, *soname
, *p
;
7752 DLLReference
*dllref
;
7754 read(fd
, &ehdr
, sizeof(ehdr
));
7756 /* test CPU specific stuff */
7757 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7758 ehdr
.e_machine
!= EM_386
)
7759 error("bad architecture");
7762 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7764 /* load dynamic section and dynamic symbols */
7768 dynsym
= NULL
; /* avoid warning */
7769 dynstr
= NULL
; /* avoid warning */
7770 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
7771 switch(sh
->sh_type
) {
7773 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
7774 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
7777 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7778 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
7779 sh1
= &shdr
[sh
->sh_link
];
7780 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
7787 /* compute the real library name */
7789 p
= strrchr(soname
, '/');
7793 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
7794 if (dt
->d_tag
== DT_SONAME
) {
7795 soname
= dynstr
+ dt
->d_un
.d_val
;
7799 /* if the dll is already loaded, do not load it */
7800 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7801 dllref
= loaded_dlls
[i
];
7802 if (!strcmp(soname
, dllref
->name
)) {
7803 /* but update level if needed */
7804 if (level
< dllref
->level
)
7805 dllref
->level
= level
;
7810 // printf("loading dll '%s'\n", soname);
7812 /* add the dll and its level */
7813 dllref
= malloc(sizeof(DLLReference
) + strlen(soname
));
7814 dllref
->level
= level
;
7815 strcpy(dllref
->name
, soname
);
7816 dynarray_add((void ***)&loaded_dlls
, &nb_loaded_dlls
, dllref
);
7818 /* add dynamic symbols in dynsym_section */
7819 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
7820 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
7821 if (sym_bind
== STB_LOCAL
)
7823 name
= dynstr
+ sym
->st_name
;
7824 add_elf_sym(dynsymtab_section
, sym
->st_value
, sym
->st_size
,
7825 sym
->st_info
, sym
->st_shndx
, name
);
7828 /* load all referenced DLLs */
7829 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
7832 name
= dynstr
+ dt
->d_un
.d_val
;
7833 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7834 dllref
= loaded_dlls
[i
];
7835 if (!strcmp(name
, dllref
->name
))
7836 goto already_loaded
;
7838 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0)
7839 error("referenced dll '%s' not found", name
);
7849 /* return -2 if error and CH_EOF if eof */
7850 static void ld_skipspaces(void)
7852 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
7856 static int ld_get_cmd(char *cmd
, int cmd_size
)
7865 if (!((ch
>= 'a' && ch
<= 'z') ||
7866 (ch
>= 'A' && ch
<= 'Z') ||
7867 (ch
>= '0' && ch
<= '9') ||
7868 strchr("/.-_+=$:\\,~?*", ch
)))
7870 if ((q
- cmd
) >= (cmd_size
- 1))
7879 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
7881 static int tcc_load_ldscript(TCCState
*s1
)
7884 char filename
[1024];
7890 ret
= ld_get_cmd(cmd
, sizeof(cmd
));
7895 // printf("cmd='%s'\n", cmd);
7896 if (!strcmp(cmd
, "INPUT") ||
7897 !strcmp(cmd
, "GROUP")) {
7903 ld_get_cmd(filename
, sizeof(filename
));
7904 tcc_add_file(s1
, filename
);
7908 } else if (ch
== ')') {
7911 } else if (ch
== CH_EOF
) {
7912 error("unexpected end of file");
7922 /* print the position in the source file of PC value 'pc' by reading
7923 the stabs debug information */
7924 static void rt_printline(unsigned long wanted_pc
)
7926 Stab_Sym
*sym
, *sym_end
;
7927 char func_name
[128];
7928 unsigned long func_addr
, last_pc
, pc
;
7929 const char *incl_files
[INCLUDE_STACK_SIZE
];
7930 int incl_index
, len
, last_line_num
, i
;
7931 const char *str
, *p
;
7933 func_name
[0] = '\0';
7936 last_pc
= 0xffffffff;
7938 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7939 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
7940 while (sym
< sym_end
) {
7941 switch(sym
->n_type
) {
7942 /* function start or end */
7944 if (sym
->n_strx
== 0) {
7945 func_name
[0] = '\0';
7948 str
= stabstr_section
->data
+ sym
->n_strx
;
7949 p
= strchr(str
, ':');
7951 pstrcpy(func_name
, sizeof(func_name
), str
);
7954 if (len
> sizeof(func_name
) - 1)
7955 len
= sizeof(func_name
) - 1;
7956 memcpy(func_name
, str
, len
);
7957 func_name
[len
] = '\0';
7959 func_addr
= sym
->n_value
;
7962 /* line number info */
7964 pc
= sym
->n_value
+ func_addr
;
7965 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7968 last_line_num
= sym
->n_desc
;
7972 str
= stabstr_section
->data
+ sym
->n_strx
;
7974 if (incl_index
< INCLUDE_STACK_SIZE
) {
7975 incl_files
[incl_index
++] = str
;
7983 if (sym
->n_strx
== 0) {
7984 incl_index
= 0; /* end of translation unit */
7986 str
= stabstr_section
->data
+ sym
->n_strx
;
7987 /* do not add path */
7989 if (len
> 0 && str
[len
- 1] != '/')
7996 /* did not find line number info: */
7997 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
8000 for(i
= 0; i
< incl_index
- 1; i
++)
8001 fprintf(stderr
, "In file included from %s\n",
8003 if (incl_index
> 0) {
8004 fprintf(stderr
, "%s:%d: ",
8005 incl_files
[incl_index
- 1], last_line_num
);
8007 if (func_name
[0] != '\0') {
8008 fprintf(stderr
, "in function '%s()': ", func_name
);
8012 /* emit a run time error at position 'pc' */
8013 void rt_error(unsigned long pc
, const char *fmt
, ...)
8019 vfprintf(stderr
, fmt
, ap
);
8020 fprintf(stderr
, "\n");
8026 /* signal handler for fatal errors */
8027 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
8029 struct ucontext
*uc
= puc
;
8033 pc
= uc
->uc_mcontext
.gregs
[14];
8035 #error please put the right sigcontext field
8040 switch(siginf
->si_code
) {
8043 rt_error(pc
, "division by zero");
8046 rt_error(pc
, "floating point exception");
8052 rt_error(pc
, "dereferencing invalid pointer");
8055 rt_error(pc
, "illegal instruction");
8058 rt_error(pc
, "abort() called");
8061 rt_error(pc
, "caught signal %d", signum
);
8068 /* launch the compiled program with the given arguments */
8069 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8072 int (*prog_main
)(int, char **);
8073 void (*bound_init
)(void);
8076 tcc_add_runtime(s1
);
8078 relocate_common_syms();
8080 /* compute relocation address : section are relocated in place */
8081 for(i
= 1; i
< nb_sections
; i
++) {
8083 if (s
->sh_flags
& SHF_ALLOC
)
8084 s
->sh_addr
= (unsigned long)s
->data
;
8089 /* relocate each section */
8090 for(i
= 1; i
< nb_sections
; i
++) {
8092 if ((s
->sh_flags
& SHF_ALLOC
) && s
->reloc
)
8093 relocate_section(s
);
8096 prog_main
= (void *)get_elf_sym_val("main");
8100 error("debug mode currently not available for Windows");
8102 struct sigaction sigact
;
8103 /* install TCC signal handlers to print debug info on fatal
8105 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8106 sigact
.sa_sigaction
= sig_error
;
8107 sigemptyset(&sigact
.sa_mask
);
8108 sigaction(SIGFPE
, &sigact
, NULL
);
8109 sigaction(SIGILL
, &sigact
, NULL
);
8110 sigaction(SIGSEGV
, &sigact
, NULL
);
8111 sigaction(SIGBUS
, &sigact
, NULL
);
8112 sigaction(SIGABRT
, &sigact
, NULL
);
8116 #ifdef CONFIG_TCC_BCHECK
8117 if (do_bounds_check
) {
8118 /* XXX: use .init section so that it also work in binary ? */
8119 bound_init
= (void *)get_elf_sym_val("__bound_init");
8123 return (*prog_main
)(argc
, argv
);
8126 TCCState
*tcc_new(void)
8131 s
= malloc(sizeof(TCCState
));
8134 s
->output_type
= TCC_OUTPUT_MEMORY
;
8136 /* default include paths */
8137 tcc_add_include_path(s
, "/usr/include");
8138 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8139 tcc_add_include_path(s
, "/usr/local/include");
8141 /* add all tokens */
8142 tok_ident
= TOK_IDENT
;
8147 tok_alloc(p
, r
- p
- 1);
8151 /* standard defines */
8152 tcc_define_symbol(s
, "__STDC__", NULL
);
8153 #if defined(TCC_TARGET_I386)
8154 tcc_define_symbol(s
, "__i386__", NULL
);
8156 /* tiny C specific defines */
8157 tcc_define_symbol(s
, "__TINYC__", NULL
);
8159 /* default library paths */
8160 tcc_add_library_path(s
, "/usr/local/lib");
8161 tcc_add_library_path(s
, "/usr/lib");
8162 tcc_add_library_path(s
, "/lib");
8164 /* no section zero */
8165 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
8167 /* create standard sections */
8168 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8169 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8170 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8172 /* symbols are always generated for linking stage */
8173 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
8174 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
8175 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
8176 put_elf_str(strtab_section
, "");
8177 symtab_section
->link
= strtab_section
;
8178 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
8179 new_section_hash(".hashtab", SHF_PRIVATE
,
8180 ELF_SYM_HASH_SIZE
, symtab_section
);
8182 /* private symbol table for dynamic symbols */
8183 dynsymtab_section
= new_section(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
);
8184 dynsymtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
8185 dynstrtab_section
= new_section(".dynstrtab", SHT_STRTAB
, SHF_PRIVATE
);
8186 put_elf_str(dynstrtab_section
, "");
8187 dynsymtab_section
->link
= dynstrtab_section
;
8188 put_elf_sym(dynsymtab_section
, 0, 0, 0, 0, 0, NULL
);
8189 new_section_hash(".dynhashtab", SHF_PRIVATE
,
8190 ELF_SYM_HASH_SIZE
, dynsymtab_section
);
8194 void tcc_delete(TCCState
*s
)
8199 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
8203 pathname1
= strdup(pathname
);
8206 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
8210 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
8215 BufferedFile
*saved_file
;
8217 /* find source file type with extension */
8218 ext
= strrchr(filename
, '.');
8224 file
= tcc_open(filename
);
8226 if (flags
& AFF_PRINT_ERROR
) {
8227 error("file '%s' not found", filename
);
8234 if (!ext
|| !strcmp(ext
, "c")) {
8235 /* C file assumed */
8239 /* assume executable format: auto guess file type */
8240 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
8241 error("could not read header");
8242 lseek(fd
, 0, SEEK_SET
);
8244 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8245 ehdr
.e_ident
[1] == ELFMAG1
&&
8246 ehdr
.e_ident
[2] == ELFMAG2
&&
8247 ehdr
.e_ident
[3] == ELFMAG3
) {
8248 file
->line_num
= 0; /* do not display line number if error */
8249 if (ehdr
.e_type
== ET_REL
) {
8250 tcc_load_object_file(s
, fd
, 0);
8251 } else if (ehdr
.e_type
== ET_DYN
) {
8252 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
8254 error("unrecognized ELF file");
8256 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8257 file
->line_num
= 0; /* do not display line number if error */
8258 tcc_load_archive(s
, fd
);
8260 /* as GNU ld, consider it is an ld script if not recognized */
8261 if (tcc_load_ldscript(s
) < 0)
8262 error("unrecognized file type");
8270 void tcc_add_file(TCCState
*s
, const char *filename
)
8272 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8275 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8279 pathname1
= strdup(pathname
);
8282 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
8286 /* find and load a dll. Return non zero if not found */
8287 /* XXX: add '-rpath' option support ? */
8288 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8293 for(i
= 0; i
< nb_library_paths
; i
++) {
8294 snprintf(buf
, sizeof(buf
), "%s/%s",
8295 library_paths
[i
], filename
);
8296 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8302 /* the library name is the same as the argument of the '-l' option */
8303 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8309 /* if we output to memory, then we simply we dlopen(). */
8310 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8311 /* Since the libc is already loaded, we don't need to load it again */
8312 if (!strcmp(libraryname
, "c"))
8314 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8315 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8321 /* first we look for the dynamic library if not static linking */
8323 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8324 if (tcc_add_dll(s
, buf
, 0) == 0)
8328 /* then we look for the static library */
8329 for(i
= 0; i
< nb_library_paths
; i
++) {
8330 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8331 library_paths
[i
], libraryname
);
8332 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8338 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8340 add_elf_sym(symtab_section
, val
, 0,
8341 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8346 int tcc_set_output_type(TCCState
*s
, int output_type
)
8348 s
->output_type
= output_type
;
8350 /* add libc crt1/crti objects */
8351 if (output_type
== TCC_OUTPUT_EXE
||
8352 output_type
== TCC_OUTPUT_DLL
) {
8353 if (output_type
!= TCC_OUTPUT_DLL
)
8354 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8355 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8360 #if !defined(LIBTCC)
8364 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8365 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8366 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
8367 " [--] infile1 [infile2... --] [infile_args...]\n"
8369 "General options:\n"
8370 " -c compile only - generate an object file\n"
8371 " -o outfile set output filename\n"
8372 " -- allows multiples input files if no -o option given. Also\n"
8373 " separate input files from runtime arguments\n"
8374 " -Bdir set tcc internal library path\n"
8375 " -bench output compilation statistics\n"
8376 "Preprocessor options:\n"
8377 " -Idir add include path 'dir'\n"
8378 " -Dsym[=val] define 'sym' with value 'val'\n"
8379 " -Usym undefine 'sym'\n"
8380 "C compiler options:\n"
8381 " -g generate runtime debug info\n"
8382 #ifdef CONFIG_TCC_BCHECK
8383 " -b compile with built-in memory and bounds checker (implies -g)\n"
8386 " -Ldir add library path 'dir'\n"
8387 " -llib link with dynamic library 'lib'\n"
8388 " -shared generate a shared library (NOT WORKING YET)\n"
8389 " -static static linking\n"
8393 int main(int argc
, char **argv
)
8396 int optind
, output_type
, multiple_files
, i
;
8402 output_type
= TCC_OUTPUT_MEMORY
;
8410 if (optind
>= argc
) {
8420 /* '--' enables multiple files input */
8422 } else if (r
[1] == 'h' || r
[1] == '?') {
8424 } else if (r
[1] == 'I') {
8425 if (tcc_add_include_path(s
, r
+ 2) < 0)
8426 error("too many include paths");
8427 } else if (r
[1] == 'D') {
8430 value
= strchr(sym
, '=');
8435 tcc_define_symbol(s
, sym
, value
);
8436 } else if (r
[1] == 'U') {
8437 tcc_undefine_symbol(s
, r
+ 2);
8438 } else if (r
[1] == 'L') {
8439 tcc_add_library_path(s
, r
+ 2);
8440 } else if (r
[1] == 'B') {
8441 /* set tcc utilities path (mainly for tcc development) */
8442 tcc_lib_path
= r
+ 2;
8443 } else if (r
[1] == 'l') {
8444 dynarray_add((void ***)&libraries
, &nb_libraries
, r
+ 2);
8445 } else if (!strcmp(r
+ 1, "bench")) {
8447 #ifdef CONFIG_TCC_BCHECK
8448 } else if (r
[1] == 'b') {
8449 if (!do_bounds_check
) {
8450 do_bounds_check
= 1;
8452 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8453 /* create bounds sections */
8454 bounds_section
= new_section(".bounds",
8455 SHT_PROGBITS
, SHF_ALLOC
);
8456 lbounds_section
= new_section(".lbounds",
8457 SHT_PROGBITS
, SHF_ALLOC
);
8458 /* debug is implied */
8462 } else if (r
[1] == 'g') {
8463 #ifdef CONFIG_TCC_BCHECK
8470 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
8471 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8472 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
8473 put_elf_str(stabstr_section
, "");
8474 stab_section
->link
= stabstr_section
;
8475 /* put first entry */
8476 put_stabs("", 0, 0, 0, 0);
8479 /* the following options are only for testing, so not
8483 output_type
= TCC_OUTPUT_OBJ
;
8484 } else if (!strcmp(r
+ 1, "static")) {
8486 } else if (!strcmp(r
+ 1, "shared")) {
8487 output_type
= TCC_OUTPUT_DLL
;
8488 } else if (r
[1] == 'o') {
8492 outfile
= argv
[optind
++];
8494 error("invalid option -- '%s'", r
);
8498 /* if outfile provided without other options, we output an
8500 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8501 output_type
= TCC_OUTPUT_EXE
;
8503 /* warning if not supported features */
8504 if (output_type
== TCC_OUTPUT_DLL
)
8505 warning("dll output is currently not supported");
8506 #ifdef CONFIG_TCC_BCHECK
8507 if (do_bounds_check
&& output_type
!= TCC_OUTPUT_MEMORY
)
8508 warning("bounds checking is currently only supported for in-memory execution");
8511 tcc_set_output_type(s
, output_type
);
8513 tcc_add_file(s
, argv
[optind
]);
8514 if (multiple_files
) {
8515 while ((optind
+ 1) < argc
) {
8520 error("'--' expected");
8527 /* add specified libraries */
8528 for(i
= 0; i
< nb_libraries
;i
++) {
8529 if (tcc_add_library(s
, libraries
[i
]) < 0)
8530 error("cannot find -l%s", libraries
[i
]);
8534 printf("total: %d idents, %d lines, %d bytes\n",
8535 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
8538 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8539 tcc_output_file(s
, outfile
);
8542 return tcc_run(s
, argc
- optind
, argv
+ optind
);