2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <sys/ucontext.h>
37 #ifndef CONFIG_TCC_STATIC
44 /* preprocessor debug */
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
64 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
65 executables or dlls */
66 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
68 /* amount of virtual memory associated to a section (currently, we do
70 #define SECTION_VSIZE (1024 * 1024)
72 #define INCLUDE_STACK_SIZE 32
73 #define IFDEF_STACK_SIZE 64
74 #define VSTACK_SIZE 64
75 #define STRING_MAX_SIZE 1024
77 #define TOK_HASH_SIZE 2048 /* must be a power of two */
78 #define TOK_ALLOC_INCR 512 /* must be a power of two */
79 #define SYM_HASH_SIZE 1031
80 #define ELF_SYM_HASH_SIZE 2048
81 #define ELF_DYNSYM_HASH_SIZE 32
83 /* token symbol management */
84 typedef struct TokenSym
{
85 struct TokenSym
*hash_next
;
86 int tok
; /* token number */
92 typedef union CValue
{
98 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
100 unsigned long long ull
;
108 typedef struct SValue
{
110 unsigned short r
; /* register + flags */
111 unsigned short r2
; /* second register, used for 'long long'
112 type. If not used, set to VT_CONST */
113 CValue c
; /* constant, if VT_CONST */
116 /* symbol management */
118 int v
; /* symbol token */
119 int t
; /* associated type */
120 int r
; /* associated register */
121 int c
; /* associated number */
122 struct Sym
*next
; /* next related symbol */
123 struct Sym
*prev
; /* prev symbol in stack */
124 struct Sym
*hash_next
; /* next symbol in hash table */
127 typedef struct SymStack
{
129 struct Sym
*hash
[SYM_HASH_SIZE
];
132 /* section definition */
133 /* XXX: use directly ELF structure for parameters ? */
134 /* special flag to indicate that the section should not be linked to
136 #define SHF_PRIVATE 0x80000000
138 typedef struct Section
{
139 unsigned char *data
; /* section data */
140 unsigned char *data_ptr
; /* current data pointer */
141 int sh_name
; /* elf section name (only used during output) */
142 int sh_num
; /* elf section number */
143 int sh_type
; /* elf section type */
144 int sh_flags
; /* elf section flags */
145 int sh_info
; /* elf section info */
146 int sh_addralign
; /* elf section alignment */
147 int sh_entsize
; /* elf entry size */
148 unsigned long sh_size
; /* section size (only used during output) */
149 unsigned long sh_addr
; /* address at which the section is relocated */
150 unsigned long sh_offset
; /* address at which the section is relocated */
151 struct Section
*link
; /* link to another section */
152 struct Section
*reloc
; /* corresponding section for relocation, if any */
153 struct Section
*hash
; /* hash table for symbols */
154 struct Section
*next
;
155 char name
[64]; /* section name */
158 typedef struct DLLReference
{
163 /* GNUC attribute definition */
164 typedef struct AttributeDef
{
167 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
170 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
171 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
172 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
174 /* stored in 'Sym.c' field */
175 #define FUNC_NEW 1 /* ansi function prototype */
176 #define FUNC_OLD 2 /* old function prototype */
177 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
179 /* stored in 'Sym.r' field */
180 #define FUNC_CDECL 0 /* standard c call */
181 #define FUNC_STDCALL 1 /* pascal c call */
183 /* field 'Sym.t' for macros */
184 #define MACRO_OBJ 0 /* object like macro */
185 #define MACRO_FUNC 1 /* function like macro */
187 /* field 'Sym.t' for labels */
188 #define LABEL_FORWARD 1 /* label is forward defined */
190 /* type_decl() types */
191 #define TYPE_ABSTRACT 1 /* type without variable */
192 #define TYPE_DIRECT 2 /* type with variable */
194 #define IO_BUF_SIZE 8192
196 typedef struct BufferedFile
{
197 unsigned char *buf_ptr
;
198 unsigned char *buf_end
;
200 int line_num
; /* current line number - here to simply code */
201 char filename
[1024]; /* current filename - here to simply code */
202 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
205 #define CH_EOB 0 /* end of buffer or '\0' char in file */
206 #define CH_EOF (-1) /* end of file */
208 /* parsing state (used to save parser state to reparse part of the
209 source several times) */
210 typedef struct ParseState
{
217 /* used to record tokens */
218 typedef struct TokenString
{
225 struct BufferedFile
*file
;
226 int ch
, ch1
, tok
, tok1
;
231 int nb_sections
; /* number of sections, including first dummy section */
232 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
233 Section
*cur_text_section
; /* current section where function code is
235 /* bound check related sections */
236 Section
*bounds_section
; /* contains global data bound description */
237 Section
*lbounds_section
; /* contains local data bound description */
238 /* symbol sections */
239 Section
*symtab_section
, *strtab_section
;
240 /* temporary dynamic symbol sections (for dll loading) */
241 Section
*dynsymtab_section
, *dynstrtab_section
;
242 /* exported dynamic symbol section */
246 unsigned long *got_offsets
;
251 /* array of all loaded dlls (including those referenced by loaded
253 DLLReference
**loaded_dlls
;
257 Section
*stab_section
, *stabstr_section
;
259 char **library_paths
;
260 int nb_library_paths
;
262 /* loc : local variable index
263 ind : output code index
265 anon_sym: anonymous symbol index
268 prog
, ind
, loc
, const_wanted
;
269 int global_expr
; /* true if compound literals must be allocated
270 globally (used during initializers parsing */
271 int func_vt
, func_vc
; /* current function return type (used by
272 return instruction) */
273 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
275 TokenSym
**table_ident
;
276 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
277 char token_buf
[STRING_MAX_SIZE
+ 1];
279 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
281 SValue vstack
[VSTACK_SIZE
], *vtop
;
282 int *macro_ptr
, *macro_ptr_allocated
;
283 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
284 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
285 char **include_paths
;
286 int nb_include_paths
;
287 int char_pointer_type
;
290 /* compile with debug symbol (and use them if error during execution) */
293 /* compile with built-in memory and bounds checker */
294 int do_bounds_check
= 0;
296 /* display benchmark infos */
301 /* use GNU C extensions */
304 /* use Tiny C extensions */
307 /* if true, static linking is performed */
314 /* The current value can be: */
315 #define VT_VALMASK 0x00ff
316 #define VT_CONST 0x00f0 /* constant in vc
317 (must be first non register value) */
318 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
319 #define VT_LOCAL 0x00f2 /* offset on stack */
320 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
321 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
322 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
323 #define VT_LVAL 0x0100 /* var is an lvalue */
324 #define VT_SYM 0x0200 /* a symbol value is added */
325 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
326 char/short stored in integer registers) */
327 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
328 dereferencing value */
329 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
330 bounding function call point is in vc */
331 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
332 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
333 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
334 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
337 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
339 #define VT_INT 0 /* integer type */
340 #define VT_BYTE 1 /* signed byte type */
341 #define VT_SHORT 2 /* short type */
342 #define VT_VOID 3 /* void type */
343 #define VT_PTR 4 /* pointer */
344 #define VT_ENUM 5 /* enum definition */
345 #define VT_FUNC 6 /* function type */
346 #define VT_STRUCT 7 /* struct/union definition */
347 #define VT_FLOAT 8 /* IEEE float */
348 #define VT_DOUBLE 9 /* IEEE double */
349 #define VT_LDOUBLE 10 /* IEEE long double */
350 #define VT_BOOL 11 /* ISOC99 boolean type */
351 #define VT_LLONG 12 /* 64 bit integer */
352 #define VT_LONG 13 /* long integer (NEVER USED as type, only
354 #define VT_BTYPE 0x000f /* mask for basic type */
355 #define VT_UNSIGNED 0x0010 /* unsigned type */
356 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
357 #define VT_BITFIELD 0x0040 /* bitfield modifier */
360 #define VT_EXTERN 0x00000080 /* extern definition */
361 #define VT_STATIC 0x00000100 /* static variable */
362 #define VT_TYPEDEF 0x00000200 /* typedef definition */
364 /* type mask (except storage) */
365 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
369 /* warning: the following compare tokens depend on i386 asm code */
381 #define TOK_LAND 0xa0
385 #define TOK_MID 0xa3 /* inc/dec, to void constant */
387 #define TOK_UDIV 0xb0 /* unsigned division */
388 #define TOK_UMOD 0xb1 /* unsigned modulo */
389 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
390 #define TOK_CINT 0xb3 /* number in tokc */
391 #define TOK_CCHAR 0xb4 /* char constant in tokc */
392 #define TOK_STR 0xb5 /* pointer to string in tokc */
393 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
394 #define TOK_LCHAR 0xb7
395 #define TOK_LSTR 0xb8
396 #define TOK_CFLOAT 0xb9 /* float constant */
397 #define TOK_LINENUM 0xba /* line number info */
398 #define TOK_CDOUBLE 0xc0 /* double constant */
399 #define TOK_CLDOUBLE 0xc1 /* long double constant */
400 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
401 #define TOK_ADDC1 0xc3 /* add with carry generation */
402 #define TOK_ADDC2 0xc4 /* add with carry use */
403 #define TOK_SUBC1 0xc5 /* add with carry generation */
404 #define TOK_SUBC2 0xc6 /* add with carry use */
405 #define TOK_CUINT 0xc8 /* unsigned int constant */
406 #define TOK_CLLONG 0xc9 /* long long constant */
407 #define TOK_CULLONG 0xca /* unsigned long long constant */
408 #define TOK_ARROW 0xcb
409 #define TOK_DOTS 0xcc /* three dots */
410 #define TOK_SHR 0xcd /* unsigned shift right */
412 #define TOK_SHL 0x01 /* shift left */
413 #define TOK_SAR 0x02 /* signed shift right */
415 /* assignement operators : normal operator or 0x80 */
416 #define TOK_A_MOD 0xa5
417 #define TOK_A_AND 0xa6
418 #define TOK_A_MUL 0xaa
419 #define TOK_A_ADD 0xab
420 #define TOK_A_SUB 0xad
421 #define TOK_A_DIV 0xaf
422 #define TOK_A_XOR 0xde
423 #define TOK_A_OR 0xfc
424 #define TOK_A_SHL 0x81
425 #define TOK_A_SAR 0x82
427 #define TOK_EOF (-1) /* end of file */
429 /* all identificators and strings have token above that */
430 #define TOK_IDENT 256
451 /* ignored types Must have contiguous values */
457 TOK___SIGNED__
, /* gcc keyword */
460 TOK___INLINE__
, /* gcc keyword */
463 /* unsupported type */
477 /* preprocessor only */
478 TOK_UIDENT
, /* first "user" ident (not keyword) */
479 TOK_DEFINE
= TOK_UIDENT
,
495 /* special identifiers */
498 #define DEF(id, str) id,
504 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
505 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
506 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
507 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
508 "sizeof\0__attribute__\0"
509 /* the following are not keywords. They are included to ease parsing */
510 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
511 "defined\0undef\0error\0line\0"
512 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
514 /* builtin functions */
515 #define DEF(id, str) str "\0"
521 #define snprintf _snprintf
524 #if defined(WIN32) || defined(TCC_UCLIBC)
525 /* currently incorrect */
526 long double strtold(const char *nptr
, char **endptr
)
528 return (long double)strtod(nptr
, endptr
);
530 float strtof(const char *nptr
, char **endptr
)
532 return (float)strtod(nptr
, endptr
);
535 /* XXX: need to define this to use them in non ISOC99 context */
536 extern float strtof (const char *__nptr
, char **__endptr
);
537 extern long double strtold (const char *__nptr
, char **__endptr
);
540 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
541 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
545 void next_nomacro(void);
546 int expr_const(void);
550 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
551 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
554 void gv2(int rc1
, int rc2
);
555 void move_reg(int r
, int s
);
556 void save_regs(int n
);
557 void save_reg(int r
);
563 void macro_subst(TokenString
*tok_str
,
564 Sym
**nested_list
, int *macro_str
);
565 int save_reg_forced(int r
);
567 void force_charshort_cast(int t
);
568 void gen_cast(int t
);
570 Sym
*sym_find(int v
);
571 Sym
*sym_push(int v
, int t
, int r
, int c
);
574 int type_size(int t
, int *a
);
575 int pointed_type(int t
);
576 int pointed_size(int t
);
577 int is_compatible_types(int t1
, int t2
);
578 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
579 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
581 void error(const char *fmt
, ...);
582 void rt_error(unsigned long pc
, const char *fmt
, ...);
584 void vset(int t
, int r
, int v
);
585 void type_to_str(char *buf
, int buf_size
,
586 int t
, const char *varstr
);
587 char *get_tok_str(int v
, CValue
*cv
);
588 Sym
*external_sym(int v
, int u
, int r
);
590 /* section generation */
591 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
);
592 void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
593 static int put_elf_str(Section
*s
, const char *sym
);
594 static int put_elf_sym(Section
*s
,
595 unsigned long value
, unsigned long size
,
596 int info
, int other
, int shndx
, const char *name
);
597 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
598 int type
, int symbol
);
599 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
600 static void put_stabn(int type
, int other
, int desc
, int value
);
601 static void put_stabd(int type
, int other
, int desc
);
602 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
604 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
605 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
606 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
608 /* true if float/double/long double type */
609 static inline int is_float(int t
)
613 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
616 #ifdef CONFIG_TCC_BCHECK
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 /* push a reference to a section offset by adding a dummy symbol */
2498 void vpush_ref(int t
, Section
*sec
, unsigned long offset
)
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
);
2509 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2512 /* push a reference to symbol v */
2513 void vpush_sym(int t
, int v
)
2518 sym
= external_sym(v
, t
, 0);
2520 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2523 void vset(int t
, int r
, int v
)
2540 void vpushv(SValue
*v
)
2542 if (vtop
>= vstack
+ VSTACK_SIZE
)
2543 error("memory full");
2553 /* save r to the memory stack, and mark it as being free */
2554 void save_reg(int r
)
2556 int l
, i
, saved
, t
, size
, align
;
2559 /* modify all stack values */
2562 for(p
=vstack
;p
<=vtop
;p
++) {
2563 i
= p
->r
& VT_VALMASK
;
2564 if ((p
->r
& VT_VALMASK
) == r
||
2565 (p
->r2
& VT_VALMASK
) == r
) {
2566 /* must save value on stack if not already done */
2568 /* store register in the stack */
2570 if ((p
->r
& VT_LVAL
) ||
2571 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2573 size
= type_size(t
, &align
);
2574 loc
= (loc
- size
) & -align
;
2576 sv
.r
= VT_LOCAL
| VT_LVAL
;
2579 #ifdef TCC_TARGET_I386
2580 /* x86 specific: need to pop fp register ST0 if saved */
2582 o(0xd9dd); /* fstp %st(1) */
2585 /* special long long case */
2586 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2593 /* mark that stack entry as being saved on the stack */
2605 /* find a free register of class 'rc'. If none, save one register */
2611 /* find a free register */
2612 for(r
=0;r
<NB_REGS
;r
++) {
2613 if (reg_classes
[r
] & rc
) {
2614 for(p
=vstack
;p
<=vtop
;p
++) {
2615 if ((p
->r
& VT_VALMASK
) == r
||
2616 (p
->r2
& VT_VALMASK
) == r
)
2624 /* no register left : free the first one on the stack (VERY
2625 IMPORTANT to start from the bottom to ensure that we don't
2626 spill registers used in gen_opi()) */
2627 for(p
=vstack
;p
<=vtop
;p
++) {
2628 r
= p
->r
& VT_VALMASK
;
2629 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2637 /* save registers up to (vtop - n) stack entry */
2638 void save_regs(int n
)
2643 for(p
= vstack
;p
<= p1
; p
++) {
2644 r
= p
->r
& VT_VALMASK
;
2651 /* move register 's' to 'r', and flush previous value of r to memory
2653 void move_reg(int r
, int s
)
2666 /* get address of vtop (vtop MUST BE an lvalue) */
2669 vtop
->r
&= ~VT_LVAL
;
2670 /* tricky: if saved lvalue, then we can go back to lvalue */
2671 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2672 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2675 #ifdef CONFIG_TCC_BCHECK
2676 /* generate lvalue bound code */
2681 vtop
->r
&= ~VT_MUSTBOUND
;
2682 /* if lvalue, then use checking code before dereferencing */
2683 if (vtop
->r
& VT_LVAL
) {
2684 /* if not VT_BOUNDED value, then make one */
2685 if (!(vtop
->r
& VT_BOUNDED
)) {
2686 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2689 gen_bounded_ptr_add();
2690 vtop
->r
|= lval_type
;
2692 /* then check for dereferencing */
2693 gen_bounded_ptr_deref();
2698 /* store vtop a register belonging to class 'rc'. lvalues are
2699 converted to values. Cannot be used if cannot be converted to
2700 register value (such as structures). */
2703 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2704 unsigned long long ll
;
2706 /* NOTE: get_reg can modify vstack[] */
2707 if (vtop
->t
& VT_BITFIELD
) {
2708 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2709 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2710 /* remove bit field info to avoid loops */
2711 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2712 /* generate shifts */
2713 vpushi(32 - (bit_pos
+ bit_size
));
2715 vpushi(32 - bit_size
);
2716 /* NOTE: transformed to SHR if unsigned */
2720 if (is_float(vtop
->t
) &&
2721 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2725 /* XXX: unify with initializers handling ? */
2726 /* CPUs usually cannot use float constants, so we store them
2727 generically in data segment */
2728 size
= type_size(vtop
->t
, &align
);
2729 data_offset
= data_section
->data_ptr
- data_section
->data
;
2730 data_offset
= (data_offset
+ align
- 1) & -align
;
2731 /* XXX: not portable yet */
2734 ((int *)(data_section
->data
+ data_offset
))[i
] = vtop
->c
.tab
[i
];
2737 sym
= sym_push1(&global_stack
, v
, vtop
->t
| VT_STATIC
, 0);
2738 sym
->r
= VT_CONST
| VT_SYM
;
2739 put_extern_sym(sym
, data_section
, data_offset
);
2741 vtop
->r
|= VT_LVAL
| VT_SYM
;
2743 data_offset
+= size
<< 2;
2744 data_section
->data_ptr
= data_section
->data
+ data_offset
;
2746 #ifdef CONFIG_TCC_BCHECK
2747 if (vtop
->r
& VT_MUSTBOUND
)
2751 r
= vtop
->r
& VT_VALMASK
;
2752 /* need to reload if:
2754 - lvalue (need to dereference pointer)
2755 - already a register, but not in the right class */
2756 if (r
>= VT_CONST
||
2757 (vtop
->r
& VT_LVAL
) ||
2758 !(reg_classes
[r
] & rc
) ||
2759 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2760 !(reg_classes
[vtop
->r2
] & rc
))) {
2762 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2763 /* two register type load : expand to two words
2765 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2768 vtop
->c
.ui
= ll
; /* first word */
2770 vtop
->r
= r
; /* save register value */
2771 vpushi(ll
>> 32); /* second word */
2772 } else if (r
>= VT_CONST
||
2773 (vtop
->r
& VT_LVAL
)) {
2774 /* load from memory */
2777 vtop
[-1].r
= r
; /* save register value */
2778 /* increment pointer to get second word */
2785 /* move registers */
2788 vtop
[-1].r
= r
; /* save register value */
2789 vtop
->r
= vtop
[-1].r2
;
2791 /* allocate second register */
2798 /* write second register */
2800 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2802 /* lvalue of scalar type : need to use lvalue type
2803 because of possible cast */
2806 /* compute memory access type */
2807 if (vtop
->r
& VT_LVAL_BYTE
)
2809 else if (vtop
->r
& VT_LVAL_SHORT
)
2811 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2815 /* restore wanted type */
2818 /* one register type load */
2827 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2828 void gv2(int rc1
, int rc2
)
2830 /* generate more generic register first */
2836 /* test if reload is needed for first register */
2837 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2847 /* test if reload is needed for first register */
2848 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2854 /* expand long long on stack in two int registers */
2859 u
= vtop
->t
& VT_UNSIGNED
;
2862 vtop
[0].r
= vtop
[-1].r2
;
2863 vtop
[0].r2
= VT_CONST
;
2864 vtop
[-1].r2
= VT_CONST
;
2865 vtop
[0].t
= VT_INT
| u
;
2866 vtop
[-1].t
= VT_INT
| u
;
2869 /* build a long long from two ints */
2872 gv2(RC_INT
, RC_INT
);
2873 vtop
[-1].r2
= vtop
[0].r
;
2878 /* rotate n first stack elements to the bottom */
2885 for(i
=-n
+1;i
!=0;i
++)
2886 vtop
[i
] = vtop
[i
+1];
2890 /* pop stack value */
2894 v
= vtop
->r
& VT_VALMASK
;
2895 #ifdef TCC_TARGET_I386
2896 /* for x86, we need to pop the FP stack */
2898 o(0xd9dd); /* fstp %st(1) */
2901 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2902 /* need to put correct jump if && or || without test */
2908 /* convert stack entry to register and duplicate its value in another
2916 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2923 /* stack: H L L1 H1 */
2931 /* duplicate value */
2942 load(r1
, &sv
); /* move r to r1 */
2944 /* duplicates value */
2949 /* generate CPU independent (unsigned) long long operations */
2950 void gen_opl(int op
)
2952 int t
, a
, b
, op1
, c
, i
;
2960 func
= TOK___divdi3
;
2963 func
= TOK___udivdi3
;
2966 func
= TOK___moddi3
;
2969 func
= TOK___umoddi3
;
2971 /* call generic long long function */
2972 gfunc_start(&gf
, FUNC_CDECL
);
2975 vpush_sym(func_old_type
, func
);
2979 vtop
->r2
= REG_LRET
;
2992 /* stack: L1 H1 L2 H2 */
2997 vtop
[-2] = vtop
[-3];
3000 /* stack: H1 H2 L1 L2 */
3006 /* stack: H1 H2 L1 L2 ML MH */
3009 /* stack: ML MH H1 H2 L1 L2 */
3013 /* stack: ML MH H1 L2 H2 L1 */
3018 /* stack: ML MH M1 M2 */
3021 } else if (op
== '+' || op
== '-') {
3022 /* XXX: add non carry method too (for MIPS or alpha) */
3028 /* stack: H1 H2 (L1 op L2) */
3031 gen_op(op1
+ 1); /* TOK_xxxC2 */
3034 /* stack: H1 H2 (L1 op L2) */
3037 /* stack: (L1 op L2) H1 H2 */
3039 /* stack: (L1 op L2) (H1 op H2) */
3047 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3052 /* stack: L H shift */
3054 /* constant: simpler */
3055 /* NOTE: all comments are for SHL. the other cases are
3056 done by swaping words */
3067 if (op
!= TOK_SAR
) {
3097 /* XXX: should provide a faster fallback on x86 ? */
3100 func
= TOK___sardi3
;
3103 func
= TOK___shrdi3
;
3106 func
= TOK___shldi3
;
3112 /* compare operations */
3118 /* stack: L1 H1 L2 H2 */
3120 vtop
[-1] = vtop
[-2];
3122 /* stack: L1 L2 H1 H2 */
3125 /* when values are equal, we need to compare low words. since
3126 the jump is inverted, we invert the test too. */
3129 else if (op1
== TOK_GT
)
3131 else if (op1
== TOK_ULT
)
3133 else if (op1
== TOK_UGT
)
3138 if (op1
!= TOK_NE
) {
3142 /* generate non equal test */
3143 /* XXX: NOT PORTABLE yet */
3147 #ifdef TCC_TARGET_I386
3148 b
= psym(0x850f, 0);
3150 error("not implemented");
3158 vset(VT_INT
, VT_JMPI
, a
);
3163 /* handle integer constant optimizations and various machine
3165 void gen_opic(int op
)
3172 /* currently, we cannot do computations with forward symbols */
3173 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3174 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3178 case '+': v1
->c
.i
+= fc
; break;
3179 case '-': v1
->c
.i
-= fc
; break;
3180 case '&': v1
->c
.i
&= fc
; break;
3181 case '^': v1
->c
.i
^= fc
; break;
3182 case '|': v1
->c
.i
|= fc
; break;
3183 case '*': v1
->c
.i
*= fc
; break;
3190 /* if division by zero, generate explicit division */
3193 error("division by zero in constant");
3197 default: v1
->c
.i
/= fc
; break;
3198 case '%': v1
->c
.i
%= fc
; break;
3199 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3200 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3203 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3204 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3205 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3207 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3208 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3209 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3210 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3211 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3212 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3213 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3214 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3215 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3216 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3218 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3219 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3225 /* if commutative ops, put c2 as constant */
3226 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3227 op
== '|' || op
== '*')) {
3232 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3235 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3236 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3242 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3243 /* try to use shifts instead of muls or divs */
3244 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3253 else if (op
== TOK_PDIV
)
3261 /* call low level op generator */
3267 /* generate a floating point operation with constant propagation */
3268 void gen_opif(int op
)
3276 /* currently, we cannot do computations with forward symbols */
3277 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3278 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3280 if (v1
->t
== VT_FLOAT
) {
3283 } else if (v1
->t
== VT_DOUBLE
) {
3291 /* NOTE: we only do constant propagation if finite number (not
3292 NaN or infinity) (ANSI spec) */
3293 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3297 case '+': f1
+= f2
; break;
3298 case '-': f1
-= f2
; break;
3299 case '*': f1
*= f2
; break;
3303 error("division by zero in constant");
3308 /* XXX: also handles tests ? */
3312 /* XXX: overflow test ? */
3313 if (v1
->t
== VT_FLOAT
) {
3315 } else if (v1
->t
== VT_DOUBLE
) {
3328 int pointed_size(int t
)
3330 return type_size(pointed_type(t
), &t
);
3334 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3336 char buf1
[256], buf2
[256];
3340 if (!is_compatible_types(t1
, t2
)) {
3341 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3342 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3343 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3348 /* generic gen_op: handles types problems */
3351 int u
, t1
, t2
, bt1
, bt2
, t
;
3355 bt1
= t1
& VT_BTYPE
;
3356 bt2
= t2
& VT_BTYPE
;
3358 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3359 /* at least one operand is a pointer */
3360 /* relationnal op: must be both pointers */
3361 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3362 // check_pointer_types(vtop, vtop - 1);
3363 /* pointers are handled are unsigned */
3364 t
= VT_INT
| VT_UNSIGNED
;
3367 /* if both pointers, then it must be the '-' op */
3368 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3369 (t2
& VT_BTYPE
) == VT_PTR
) {
3371 error("cannot use pointers here");
3372 // check_pointer_types(vtop - 1, vtop);
3373 /* XXX: check that types are compatible */
3374 u
= pointed_size(t1
);
3376 /* set to integer type */
3381 /* exactly one pointer : must be '+' or '-'. */
3382 if (op
!= '-' && op
!= '+')
3383 error("cannot use pointers here");
3384 /* Put pointer as first operand */
3385 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3389 /* XXX: cast to int ? (long long case) */
3390 vpushi(pointed_size(vtop
[-1].t
));
3392 #ifdef CONFIG_TCC_BCHECK
3393 /* if evaluating constant expression, no code should be
3394 generated, so no bound check */
3395 if (do_bounds_check
&& !const_wanted
) {
3396 /* if bounded pointers, we generate a special code to
3403 gen_bounded_ptr_add();
3409 /* put again type if gen_opic() swaped operands */
3412 } else if (is_float(bt1
) || is_float(bt2
)) {
3413 /* compute bigger type and do implicit casts */
3414 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3416 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3421 /* floats can only be used for a few operations */
3422 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3423 (op
< TOK_ULT
|| op
> TOK_GT
))
3424 error("invalid operands for binary operation");
3426 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3427 /* cast to biggest op */
3429 /* convert to unsigned if it does not fit in a long long */
3430 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3431 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3435 /* integer operations */
3437 /* convert to unsigned if it does not fit in an integer */
3438 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3439 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3442 /* XXX: currently, some unsigned operations are explicit, so
3443 we modify them here */
3444 if (t
& VT_UNSIGNED
) {
3451 else if (op
== TOK_LT
)
3453 else if (op
== TOK_GT
)
3455 else if (op
== TOK_LE
)
3457 else if (op
== TOK_GE
)
3463 /* special case for shifts and long long: we keep the shift as
3465 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3471 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3475 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3476 /* relationnal op: the result is an int */
3484 /* generic itof for unsigned long long case */
3485 void gen_cvt_itof1(int t
)
3489 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3490 (VT_LLONG
| VT_UNSIGNED
)) {
3492 gfunc_start(&gf
, FUNC_CDECL
);
3495 vpush_sym(func_old_type
, TOK___ulltof
);
3496 else if (t
== VT_DOUBLE
)
3497 vpush_sym(func_old_type
, TOK___ulltod
);
3499 vpush_sym(func_old_type
, TOK___ulltold
);
3508 /* generic ftoi for unsigned long long case */
3509 void gen_cvt_ftoi1(int t
)
3514 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3515 /* not handled natively */
3516 gfunc_start(&gf
, FUNC_CDECL
);
3517 st
= vtop
->t
& VT_BTYPE
;
3520 vpush_sym(func_old_type
, TOK___fixunssfdi
);
3521 else if (st
== VT_DOUBLE
)
3522 vpush_sym(func_old_type
, TOK___fixunsdfdi
);
3524 vpush_sym(func_old_type
, TOK___fixunsxfdi
);
3528 vtop
->r2
= REG_LRET
;
3534 /* force char or short cast */
3535 void force_charshort_cast(int t
)
3539 /* XXX: add optimization if lvalue : just change type and offset */
3544 if (t
& VT_UNSIGNED
) {
3545 vpushi((1 << bits
) - 1);
3556 /* cast 'vtop' to 't' type */
3557 void gen_cast(int t
)
3559 int sbt
, dbt
, sf
, df
, c
;
3561 /* special delayed cast for char/short */
3562 /* XXX: in some cases (multiple cascaded casts), it may still
3564 if (vtop
->r
& VT_MUSTCAST
) {
3565 vtop
->r
&= ~VT_MUSTCAST
;
3566 force_charshort_cast(vtop
->t
);
3569 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3570 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3575 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3577 /* convert from fp to fp */
3579 /* constant case: we can do it now */
3580 /* XXX: in ISOC, cannot do it if error in convert */
3581 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3582 vtop
->c
.f
= (float)vtop
->c
.d
;
3583 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3584 vtop
->c
.f
= (float)vtop
->c
.ld
;
3585 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3586 vtop
->c
.d
= (double)vtop
->c
.f
;
3587 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3588 vtop
->c
.d
= (double)vtop
->c
.ld
;
3589 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3590 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3591 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3592 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3594 /* non constant case: generate code */
3598 /* convert int to fp */
3601 case VT_LLONG
| VT_UNSIGNED
:
3603 /* XXX: add const cases for long long */
3605 case VT_INT
| VT_UNSIGNED
:
3607 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3608 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3609 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3614 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3615 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3616 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3625 /* convert fp to int */
3626 /* we handle char/short/etc... with generic code */
3627 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3628 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3633 case VT_LLONG
| VT_UNSIGNED
:
3635 /* XXX: add const cases for long long */
3637 case VT_INT
| VT_UNSIGNED
:
3639 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3640 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3641 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3647 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3648 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3649 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3657 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3658 /* additionnal cast for char/short/bool... */
3662 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3663 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3664 /* scalar to long long */
3666 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3667 vtop
->c
.ll
= vtop
->c
.ui
;
3669 vtop
->c
.ll
= vtop
->c
.i
;
3671 /* machine independant conversion */
3673 /* generate high word */
3674 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3682 /* patch second register */
3683 vtop
[-1].r2
= vtop
->r
;
3687 } else if (dbt
== VT_BOOL
) {
3688 /* scalar to bool */
3691 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3692 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3693 force_charshort_cast(t
);
3694 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3696 if (sbt
== VT_LLONG
) {
3697 /* from long long: just take low order word */
3701 /* if lvalue and single word type, nothing to do because
3702 the lvalue already contains the real type size (see
3703 VT_LVAL_xxx constants) */
3709 /* return type size. Put alignment at 'a' */
3710 int type_size(int t
, int *a
)
3716 if (bt
== VT_STRUCT
) {
3718 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3719 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3721 } else if (bt
== VT_PTR
) {
3723 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3724 return type_size(s
->t
, a
) * s
->c
;
3729 } else if (bt
== VT_LDOUBLE
) {
3731 return LDOUBLE_SIZE
;
3732 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3735 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3738 } else if (bt
== VT_SHORT
) {
3742 /* char, void, function, _Bool */
3748 /* return the pointed type of t */
3749 int pointed_type(int t
)
3752 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3753 return s
->t
| (t
& ~VT_TYPE
);
3756 int mk_pointer(int t
)
3760 sym_push(p
, t
, 0, -1);
3761 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3764 int is_compatible_types(int t1
, int t2
)
3771 bt1
= t1
& VT_BTYPE
;
3772 bt2
= t2
& VT_BTYPE
;
3773 if (bt1
== VT_PTR
) {
3774 t1
= pointed_type(t1
);
3775 /* if function, then convert implicitely to function pointer */
3776 if (bt2
!= VT_FUNC
) {
3779 t2
= pointed_type(t2
);
3781 /* void matches everything */
3784 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3786 return is_compatible_types(t1
, t2
);
3787 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3789 } else if (bt1
== VT_FUNC
) {
3792 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3793 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3794 if (!is_compatible_types(s1
->t
, s2
->t
))
3796 /* XXX: not complete */
3797 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3801 while (s1
!= NULL
) {
3804 if (!is_compatible_types(s1
->t
, s2
->t
))
3813 /* XXX: not complete */
3818 /* print a type. If 'varstr' is not NULL, then the variable is also
3819 printed in the type */
3821 /* XXX: add array and function pointers */
3822 void type_to_str(char *buf
, int buf_size
,
3823 int t
, const char *varstr
)
3833 if (t
& VT_UNSIGNED
)
3834 pstrcat(buf
, buf_size
, "unsigned ");
3864 tstr
= "long double";
3866 pstrcat(buf
, buf_size
, tstr
);
3870 if (bt
== VT_STRUCT
)
3874 pstrcat(buf
, buf_size
, tstr
);
3875 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3876 if (v
>= SYM_FIRST_ANOM
)
3877 pstrcat(buf
, buf_size
, "<anonymous>");
3879 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3882 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3883 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3884 pstrcat(buf
, buf_size
, "(");
3886 while (sa
!= NULL
) {
3887 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3888 pstrcat(buf
, buf_size
, buf1
);
3891 pstrcat(buf
, buf_size
, ", ");
3893 pstrcat(buf
, buf_size
, ")");
3896 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3897 pstrcpy(buf1
, sizeof(buf1
), "*");
3899 pstrcat(buf1
, sizeof(buf1
), varstr
);
3900 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3904 pstrcat(buf
, buf_size
, " ");
3905 pstrcat(buf
, buf_size
, varstr
);
3910 /* verify type compatibility to store vtop in 'dt' type, and generate
3912 void gen_assign_cast(int dt
)
3915 char buf1
[256], buf2
[256];
3917 st
= vtop
->t
; /* source type */
3918 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3919 /* special cases for pointers */
3920 /* a function is implicitely a function pointer */
3921 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3922 if (!is_compatible_types(pointed_type(dt
), st
))
3927 /* '0' can also be a pointer */
3928 if ((st
& VT_BTYPE
) == VT_INT
&&
3929 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3933 if (!is_compatible_types(dt
, st
)) {
3935 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3936 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3937 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3943 /* store vtop in lvalue pushed on stack */
3946 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3950 sbt
= vtop
->t
& VT_BTYPE
;
3951 dbt
= ft
& VT_BTYPE
;
3952 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3953 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3954 /* optimize char/short casts */
3955 delayed_cast
= VT_MUSTCAST
;
3956 vtop
->t
= ft
& VT_TYPE
;
3959 gen_assign_cast(ft
& VT_TYPE
);
3962 if (sbt
== VT_STRUCT
) {
3963 /* if structure, only generate pointer */
3964 /* structure assignment : generate memcpy */
3965 /* XXX: optimize if small size */
3967 gfunc_start(&gf
, FUNC_CDECL
);
3969 size
= type_size(vtop
->t
, &align
);
3983 vpush_sym(func_old_type
, TOK_memcpy
);
3985 /* leave source on stack */
3986 } else if (ft
& VT_BITFIELD
) {
3987 /* bitfield store handling */
3988 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3989 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3990 /* remove bit field info to avoid loops */
3991 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3993 /* duplicate destination */
3995 vtop
[-1] = vtop
[-2];
3997 /* mask and shift source */
3998 vpushi((1 << bit_size
) - 1);
4002 /* load destination, mask and or with source */
4004 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4010 #ifdef CONFIG_TCC_BCHECK
4011 /* bound check case */
4012 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4021 r
= gv(rc
); /* generate value */
4022 /* if lvalue was saved on stack, must read it */
4023 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4025 t
= get_reg(RC_INT
);
4027 sv
.r
= VT_LOCAL
| VT_LVAL
;
4028 sv
.c
.ul
= vtop
[-1].c
.ul
;
4030 vtop
[-1].r
= t
| VT_LVAL
;
4033 /* two word case handling : store second register at word + 4 */
4034 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4036 /* convert to int to increment easily */
4043 /* XXX: it works because r2 is spilled last ! */
4044 store(vtop
->r2
, vtop
- 1);
4047 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4048 vtop
->r
|= delayed_cast
;
4052 /* post defines POST/PRE add. c is the token ++ or -- */
4053 void inc(int post
, int c
)
4056 vdup(); /* save lvalue */
4058 gv_dup(); /* duplicate value */
4063 vpushi(c
- TOK_MID
);
4065 vstore(); /* store value */
4067 vpop(); /* if post op, return saved value */
4070 /* Parse GNUC __attribute__ extension. Currently, the following
4071 extensions are recognized:
4072 - aligned(n) : set data/function alignment.
4073 - section(x) : generate data/code in this section.
4074 - unused : currently ignored, but may be used someday.
4076 void parse_attribute(AttributeDef
*ad
)
4083 while (tok
!= ')') {
4084 if (tok
< TOK_IDENT
)
4085 expect("attribute name");
4090 case TOK___SECTION__
:
4093 expect("section name");
4094 ad
->section
= find_section(tokc
.ts
->str
);
4099 case TOK___ALIGNED__
:
4102 if (n
<= 0 || (n
& (n
- 1)) != 0)
4103 error("alignment must be a positive power of two");
4108 case TOK___UNUSED__
:
4109 /* currently, no need to handle it because tcc does not
4110 track unused objects */
4113 case TOK___NORETURN__
:
4114 /* currently, no need to handle it because tcc does not
4115 track unused objects */
4120 ad
->func_call
= FUNC_CDECL
;
4124 case TOK___STDCALL__
:
4125 ad
->func_call
= FUNC_STDCALL
;
4128 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4129 /* skip parameters */
4130 /* XXX: skip parenthesis too */
4133 while (tok
!= ')' && tok
!= -1)
4147 /* enum/struct/union declaration */
4148 int struct_decl(int u
)
4150 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4151 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4155 a
= tok
; /* save decl type */
4160 /* struct already defined ? return it */
4161 /* XXX: check consistency */
4162 s
= sym_find(v
| SYM_STRUCT
);
4165 error("invalid type");
4171 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4172 /* put struct/union/enum name in type */
4174 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4179 error("struct/union/enum already defined");
4180 /* cannot be empty */
4187 if (a
== TOK_ENUM
) {
4194 /* enum symbols have static storage */
4195 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4200 parse_btype(&b
, &ad
);
4205 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4206 if ((t
& VT_BTYPE
) == VT_FUNC
||
4207 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4208 error("invalid type for '%s'",
4209 get_tok_str(v
, NULL
));
4215 bit_size
= expr_const();
4216 /* XXX: handle v = 0 case for messages */
4218 error("negative width in bit-field '%s'",
4219 get_tok_str(v
, NULL
));
4220 if (v
&& bit_size
== 0)
4221 error("zero width for bit-field '%s'",
4222 get_tok_str(v
, NULL
));
4224 size
= type_size(t
, &align
);
4226 if (bit_size
>= 0) {
4231 error("bitfields must have scalar type");
4233 if (bit_size
> bsize
) {
4234 error("width of '%s' exceeds its type",
4235 get_tok_str(v
, NULL
));
4236 } else if (bit_size
== bsize
) {
4237 /* no need for bit fields */
4239 } else if (bit_size
== 0) {
4240 /* XXX: what to do if only padding in a
4242 /* zero size: means to pad */
4246 /* we do not have enough room ? */
4247 if ((bit_pos
+ bit_size
) > bsize
)
4250 /* XXX: handle LSB first */
4252 (bit_pos
<< VT_STRUCT_SHIFT
) |
4253 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4254 bit_pos
+= bit_size
;
4260 /* add new memory data only if starting
4262 if (lbit_pos
== 0) {
4263 if (a
== TOK_STRUCT
) {
4264 c
= (c
+ align
- 1) & -align
;
4272 if (align
> maxalign
)
4276 printf("add field %s offset=%d",
4277 get_tok_str(v
, NULL
), offset
);
4278 if (t
& VT_BITFIELD
) {
4279 printf(" pos=%d size=%d",
4280 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4281 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4285 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4289 if (tok
== ';' || tok
== -1)
4299 /* size for struct/union, dummy for enum */
4300 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4305 /* return 0 if no type declaration. otherwise, return the basic type
4308 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4310 int t
, u
, type_found
;
4313 memset(ad
, 0, sizeof(AttributeDef
));
4324 if ((t
& VT_BTYPE
) != 0)
4325 error("too many basic types");
4339 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4340 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4341 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4342 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4356 if ((t
& VT_BTYPE
) == VT_LONG
) {
4357 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4364 u
= struct_decl(VT_ENUM
);
4368 u
= struct_decl(VT_STRUCT
);
4371 /* type modifiers */
4376 case TOK___SIGNED__
:
4379 case TOK___INLINE__
:
4401 /* GNUC attribute */
4402 case TOK___ATTRIBUTE__
:
4403 parse_attribute(ad
);
4407 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4409 t
|= (s
->t
& ~VT_TYPEDEF
);
4416 /* long is never used as type */
4417 if ((t
& VT_BTYPE
) == VT_LONG
)
4418 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4423 int post_type(int t
, AttributeDef
*ad
)
4425 int p
, n
, pt
, l
, t1
;
4426 Sym
**plast
, *s
, *first
;
4430 /* function declaration */
4435 while (tok
!= ')') {
4436 /* read param name and compute offset */
4437 if (l
!= FUNC_OLD
) {
4438 if (!parse_btype(&pt
, &ad1
)) {
4440 error("invalid type");
4447 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4449 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4450 if ((pt
& VT_BTYPE
) == VT_VOID
)
4451 error("parameter declared as void");
4458 /* array must be transformed to pointer according to ANSI C */
4460 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4465 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4472 /* if no parameters, then old type prototype */
4476 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4477 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4478 /* we push a anonymous symbol which will contain the function prototype */
4480 s
= sym_push(p
, t
, ad
->func_call
, l
);
4482 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4483 } else if (tok
== '[') {
4484 /* array definition */
4490 error("invalid array size");
4493 /* parse next post type */
4494 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4495 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4497 /* we push a anonymous symbol which will contain the array
4500 sym_push(p
, t
, 0, n
);
4501 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4506 /* Read a type declaration (except basic type), and return the
4507 type. 'td' is a bitmask indicating which kind of type decl is
4508 expected. 't' should contain the basic type. 'ad' is the attribute
4509 definition of the basic type. It can be modified by type_decl(). */
4510 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4515 while (tok
== '*') {
4517 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4522 /* recursive type */
4523 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4526 /* XXX: this is not correct to modify 'ad' at this point, but
4527 the syntax is not clear */
4528 if (tok
== TOK___ATTRIBUTE__
)
4529 parse_attribute(ad
);
4530 u
= type_decl(ad
, v
, 0, td
);
4534 /* type identifier */
4535 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4539 if (!(td
& TYPE_ABSTRACT
))
4540 expect("identifier");
4544 /* append t at the end of u */
4545 t
= post_type(t
, ad
);
4546 if (tok
== TOK___ATTRIBUTE__
)
4547 parse_attribute(ad
);
4552 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4562 /* define a new external reference to a symbol 'v' of type 'u' */
4563 Sym
*external_sym(int v
, int u
, int r
)
4569 /* push forward reference */
4570 s
= sym_push1(&global_stack
,
4571 v
, u
| VT_EXTERN
, 0);
4572 s
->r
= r
| VT_CONST
| VT_SYM
;
4577 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4578 static int lvalue_type(int t
)
4585 else if (bt
== VT_SHORT
)
4589 if (t
& VT_UNSIGNED
)
4590 r
|= VT_LVAL_UNSIGNED
;
4594 /* indirection with full error checking and bound check */
4595 static void indir(void)
4597 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4599 if (vtop
->r
& VT_LVAL
)
4601 vtop
->t
= pointed_type(vtop
->t
);
4602 /* an array is never an lvalue */
4603 if (!(vtop
->t
& VT_ARRAY
)) {
4604 vtop
->r
|= lvalue_type(vtop
->t
);
4605 /* if bound checking, the referenced pointer must be checked */
4606 if (do_bounds_check
)
4607 vtop
->r
|= VT_MUSTBOUND
;
4611 /* pass a parameter to a function and do type checking and casting */
4612 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4615 func_type
= func
->c
;
4616 if (func_type
== FUNC_OLD
||
4617 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4618 /* default casting : only need to convert float to double */
4619 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4620 gen_cast(VT_DOUBLE
);
4621 } else if (arg
== NULL
) {
4622 error("too many arguments to function");
4624 gen_assign_cast(arg
->t
);
4631 int n
, t
, ft
, fc
, align
, size
, r
, data_offset
;
4636 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4639 } else if (tok
== TOK_CUINT
) {
4640 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4642 } else if (tok
== TOK_CLLONG
) {
4643 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4645 } else if (tok
== TOK_CULLONG
) {
4646 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4648 } else if (tok
== TOK_CFLOAT
) {
4649 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4651 } else if (tok
== TOK_CDOUBLE
) {
4652 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4654 } else if (tok
== TOK_CLDOUBLE
) {
4655 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4657 } else if (tok
== TOK___FUNC__
) {
4658 /* special function name identifier */
4659 /* generate (char *) type */
4660 data_offset
= data_section
->data_ptr
- data_section
->data
;
4661 vpush_ref(mk_pointer(VT_BYTE
), data_section
, data_offset
);
4662 strcpy(data_section
->data
+ data_offset
, funcname
);
4663 data_offset
+= strlen(funcname
) + 1;
4664 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4666 } else if (tok
== TOK_LSTR
) {
4669 } else if (tok
== TOK_STR
) {
4670 /* string parsing */
4673 type_size(t
, &align
);
4674 data_offset
= data_section
->data_ptr
- data_section
->data
;
4675 data_offset
= (data_offset
+ align
- 1) & -align
;
4677 /* we must declare it as an array first to use initializer parser */
4678 t
= VT_ARRAY
| mk_pointer(t
);
4679 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4680 data_offset
+= type_size(t
, &align
);
4681 /* put it as pointer */
4682 vpush_ref(t
& ~VT_ARRAY
, data_section
, fc
);
4683 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4689 if (parse_btype(&t
, &ad
)) {
4690 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4692 /* check ISOC99 compound literal */
4694 /* data is allocated locally by default */
4699 /* all except arrays are lvalues */
4700 if (!(ft
& VT_ARRAY
))
4701 r
|= lvalue_type(ft
);
4702 memset(&ad
, 0, sizeof(AttributeDef
));
4703 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4712 } else if (t
== '*') {
4715 } else if (t
== '&') {
4717 /* functions names must be treated as function pointers,
4718 except for unary '&' and sizeof. Since we consider that
4719 functions are not lvalues, we only have to handle it
4720 there and in function calls. */
4721 /* arrays can also be used although they are not lvalues */
4722 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4723 !(vtop
->t
& VT_ARRAY
))
4725 vtop
->t
= mk_pointer(vtop
->t
);
4730 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4731 vtop
->c
.i
= !vtop
->c
.i
;
4732 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4733 vtop
->c
.i
= vtop
->c
.i
^ 1;
4735 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4745 if (t
== TOK_SIZEOF
) {
4748 if (parse_btype(&t
, &ad
)) {
4749 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4751 /* XXX: some code could be generated: add eval
4763 vpushi(type_size(t
, &t
));
4765 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4768 } else if (t
== '-') {
4775 expect("identifier");
4779 error("'%s' undeclared", get_tok_str(t
, NULL
));
4780 /* for simple function calls, we tolerate undeclared
4781 external reference to int() function */
4782 s
= external_sym(t
, func_old_type
, 0);
4784 vset(s
->t
, s
->r
, s
->c
);
4785 /* if forward reference, we must point to s */
4786 if (vtop
->r
& VT_SYM
)
4791 /* post operations */
4793 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4796 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4798 if (tok
== TOK_ARROW
)
4803 /* expect pointer on structure */
4804 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4805 expect("struct or union");
4806 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4809 while ((s
= s
->next
) != NULL
) {
4814 error("field not found");
4815 /* add field offset to pointer */
4816 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4819 /* change type to field type, and set to lvalue */
4821 /* an array is never an lvalue */
4822 if (!(vtop
->t
& VT_ARRAY
))
4823 vtop
->r
|= lvalue_type(vtop
->t
);
4825 } else if (tok
== '[') {
4831 } else if (tok
== '(') {
4836 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4837 /* pointer test (no array accepted) */
4838 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4839 vtop
->t
= pointed_type(vtop
->t
);
4840 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4844 expect("function pointer");
4847 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4849 /* get return type */
4850 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4851 save_regs(0); /* save used temporary registers */
4852 gfunc_start(&gf
, s
->r
);
4854 sa
= s
->next
; /* first parameter */
4855 #ifdef INVERT_FUNC_PARAMS
4859 ParseState saved_parse_state
;
4862 /* read each argument and store it on a stack */
4863 /* XXX: merge it with macro args ? */
4869 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4873 else if (tok
== ')')
4875 tok_str_add_tok(&str
);
4878 tok_str_add(&str
, -1); /* end of file added */
4879 tok_str_add(&str
, 0);
4880 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4881 s1
->next
= sa
; /* add reference to argument */
4890 /* now generate code in reverse order by reading the stack */
4891 save_parse_state(&saved_parse_state
);
4893 macro_ptr
= (int *)args
->c
;
4897 expect("',' or ')'");
4898 gfunc_param_typed(&gf
, s
, args
->next
);
4900 free((int *)args
->c
);
4904 restore_parse_state(&saved_parse_state
);
4907 /* compute first implicit argument if a structure is returned */
4908 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4909 /* get some space for the returned structure */
4910 size
= type_size(s
->t
, &align
);
4911 loc
= (loc
- size
) & -align
;
4913 ret
.r
= VT_LOCAL
| VT_LVAL
;
4914 /* pass it as 'int' to avoid structure arg passing
4916 vset(VT_INT
, VT_LOCAL
, loc
);
4922 /* return in register */
4923 if (is_float(ret
.t
)) {
4926 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4932 #ifndef INVERT_FUNC_PARAMS
4936 gfunc_param_typed(&gf
, s
, sa
);
4946 error("too few arguments to function");
4950 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4964 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4965 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4966 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4989 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4990 (l
== 1 && (tok
== '+' || tok
== '-')) ||
4991 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
4992 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4993 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
4994 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
4995 (l
== 5 && tok
== '&') ||
4996 (l
== 6 && tok
== '^') ||
4997 (l
== 7 && tok
== '|') ||
4998 (l
== 8 && tok
== TOK_LAND
) ||
4999 (l
== 9 && tok
== TOK_LOR
)) {
5008 /* only used if non constant */
5016 if (tok
!= TOK_LAND
) {
5019 vset(VT_INT
, VT_JMPI
, t
);
5036 if (tok
!= TOK_LOR
) {
5039 vset(VT_INT
, VT_JMP
, t
);
5049 /* XXX: better constant handling */
5052 int t
, u
, c
, r1
, r2
, rc
;
5072 save_regs(1); /* we need to save all registers here except
5073 at the top because it is a branch point */
5076 /* XXX: long long handling ? */
5078 if (is_float(vtop
->t
))
5081 vtop
--; /* no vpop so that FP stack is not flushed */
5106 /* parse a constant expression and return value in vtop */
5107 void expr_const1(void)
5113 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5118 /* parse an integer constant and return its value */
5119 int expr_const(void)
5128 /* return the label token if current token is a label, otherwise
5135 /* fast test first */
5136 if (tok
< TOK_UIDENT
)
5138 /* no need to save tokc since we expect an identifier */
5146 /* XXX: may not work in all cases (macros ?) */
5155 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5160 /* generate line number info */
5162 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5163 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5165 last_line_num
= file
->line_num
;
5168 if (tok
== TOK_IF
) {
5175 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5177 if (c
== TOK_ELSE
) {
5181 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5182 gsym(d
); /* patch else jmp */
5185 } else if (tok
== TOK_WHILE
) {
5193 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5197 } else if (tok
== '{') {
5200 s
= local_stack
.top
;
5201 while (tok
!= '}') {
5204 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5206 /* pop locally defined symbols */
5207 sym_pop(&local_stack
, s
);
5209 } else if (tok
== TOK_RETURN
) {
5213 gen_assign_cast(func_vt
);
5214 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5215 /* if returning structure, must copy it to implicit
5216 first pointer arg location */
5217 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5220 /* copy structure value to pointer */
5222 } else if (is_float(func_vt
)) {
5227 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5230 rsym
= gjmp(rsym
); /* jmp */
5231 } else if (tok
== TOK_BREAK
) {
5234 error("cannot break");
5235 *bsym
= gjmp(*bsym
);
5238 } else if (tok
== TOK_CONTINUE
) {
5241 error("cannot continue");
5242 *csym
= gjmp(*csym
);
5245 } else if (tok
== TOK_FOR
) {
5272 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5277 if (tok
== TOK_DO
) {
5282 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5293 if (tok
== TOK_SWITCH
) {
5297 /* XXX: other types than integer */
5298 case_reg
= gv(RC_INT
);
5302 b
= gjmp(0); /* jump to first case */
5304 block(&a
, csym
, &b
, &c
, case_reg
);
5305 /* if no default, jmp after switch */
5313 if (tok
== TOK_CASE
) {
5320 if (gnu_ext
&& tok
== TOK_DOTS
) {
5324 warning("empty case range");
5326 /* since a case is like a label, we must skip it with a jmp */
5329 vset(VT_INT
, case_reg
, 0);
5333 *case_sym
= gtst(1, 0);
5336 *case_sym
= gtst(1, 0);
5337 vset(VT_INT
, case_reg
, 0);
5340 *case_sym
= gtst(1, *case_sym
);
5344 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5346 if (tok
== TOK_DEFAULT
) {
5352 error("too many 'default'");
5354 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5356 if (tok
== TOK_GOTO
) {
5358 s
= sym_find1(&label_stack
, tok
);
5359 /* put forward definition if needed */
5361 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5362 /* label already defined */
5363 if (s
->t
& LABEL_FORWARD
)
5373 s
= sym_find1(&label_stack
, b
);
5375 if (!(s
->t
& LABEL_FORWARD
))
5376 error("multiple defined label");
5381 sym_push1(&label_stack
, b
, 0, ind
);
5383 /* we accept this, but it is a mistake */
5385 warning("deprecated use of label at end of compound statement");
5387 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5389 /* expression case */
5399 /* t is the array or struct type. c is the array or struct
5400 address. cur_index/cur_field is the pointer to the current
5401 value. 'size_only' is true if only size info is needed (only used
5403 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5404 int *cur_index
, Sym
**cur_field
,
5408 int notfirst
, index
, align
, l
;
5411 if (gnu_ext
&& (l
= is_label()) != 0)
5414 while (tok
== '[' || tok
== '.') {
5416 if (!(t
& VT_ARRAY
))
5417 expect("array type");
5418 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5420 index
= expr_const();
5421 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5422 expect("invalid index");
5426 t
= pointed_type(t
);
5427 c
+= index
* type_size(t
, &align
);
5433 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5434 expect("struct/union type");
5435 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5447 t
= f
->t
| (t
& ~VT_TYPE
);
5462 t
= pointed_type(t
);
5463 c
+= index
* type_size(t
, &align
);
5467 error("too many field init");
5468 t
= f
->t
| (t
& ~VT_TYPE
);
5472 decl_initializer(t
, sec
, c
, 0, size_only
);
5476 #define EXPR_CONST 1
5479 /* store a value or an expression directly in global data or in local array */
5480 void init_putv(int t
, Section
*sec
, unsigned long c
,
5481 int v
, int expr_type
)
5483 int saved_global_expr
, bt
;
5491 /* compound literals must be allocated globally in this case */
5492 saved_global_expr
= global_expr
;
5495 global_expr
= saved_global_expr
;
5503 /* XXX: not portable */
5504 /* XXX: generate error if incorrect relocation */
5507 ptr
= sec
->data
+ c
;
5508 if ((vtop
->r
& VT_SYM
) &&
5514 error("initializer element is not computable at load time");
5517 *(char *)ptr
= vtop
->c
.i
;
5520 *(short *)ptr
= vtop
->c
.i
;
5523 *(double *)ptr
= vtop
->c
.d
;
5526 *(long double *)ptr
= vtop
->c
.ld
;
5529 *(long long *)ptr
= vtop
->c
.ll
;
5532 if (vtop
->r
& VT_SYM
) {
5533 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5536 *(int *)ptr
= vtop
->c
.i
;
5542 vset(t
, VT_LOCAL
, c
);
5549 /* put zeros for variable based init */
5550 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5555 /* nothing to do because globals are already set to zero */
5557 gfunc_start(&gf
, FUNC_CDECL
);
5562 vset(VT_INT
, VT_LOCAL
, c
);
5564 vpush_sym(func_old_type
, TOK_memset
);
5569 /* 't' contains the type and storage info. 'c' is the offset of the
5570 object in section 'sec'. If 'sec' is NULL, it means stack based
5571 allocation. 'first' is true if array '{' must be read (multi
5572 dimension implicit array init handling). 'size_only' is true if
5573 size only evaluation is wanted (only for arrays). */
5574 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5576 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5577 int t1
, size1
, align1
, expr_type
;
5582 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5585 t1
= pointed_type(t
);
5586 size1
= type_size(t1
, &align1
);
5589 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5595 /* only parse strings here if correct type (otherwise: handle
5596 them as ((w)char *) expressions */
5597 if ((tok
== TOK_LSTR
&&
5598 (t1
& VT_BTYPE
) == VT_INT
) ||
5600 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5601 /* XXX: move multiple string parsing in parser ? */
5602 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5604 /* compute maximum number of chars wanted */
5606 if (n
>= 0 && nb
> (n
- array_length
))
5607 nb
= n
- array_length
;
5610 warning("initializer-string for array is too long");
5612 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5613 ts
->str
[i
], EXPR_VAL
);
5619 /* only add trailing zero if enough storage (no
5620 warning in this case since it is standard) */
5621 if (n
< 0 || array_length
< n
) {
5623 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5629 while (tok
!= '}') {
5630 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5631 if (n
>= 0 && index
>= n
)
5632 error("index too large");
5633 /* must put zero in holes (note that doing it that way
5634 ensures that it even works with designators) */
5635 if (!size_only
&& array_length
< index
) {
5636 init_putz(t1
, sec
, c
+ array_length
* size1
,
5637 (index
- array_length
) * size1
);
5640 if (index
> array_length
)
5641 array_length
= index
;
5642 /* special test for multi dimensional arrays (may not
5643 be strictly correct if designators are used at the
5645 if (index
>= n
&& no_oblock
)
5654 /* put zeros at the end */
5655 if (!size_only
&& n
>= 0 && array_length
< n
) {
5656 init_putz(t1
, sec
, c
+ array_length
* size1
,
5657 (n
- array_length
) * size1
);
5659 /* patch type size if needed */
5661 s
->c
= array_length
;
5662 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5663 /* XXX: union needs only one init */
5665 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5670 while (tok
!= '}') {
5671 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5672 /* fill with zero between fields */
5674 if (!size_only
&& array_length
< index
) {
5675 init_putz(t
, sec
, c
+ array_length
,
5676 index
- array_length
);
5678 index
= index
+ type_size(f
->t
, &align1
);
5679 if (index
> array_length
)
5680 array_length
= index
;
5686 /* put zeros at the end */
5687 if (!size_only
&& array_length
< n
) {
5688 init_putz(t
, sec
, c
+ array_length
,
5692 } else if (tok
== '{') {
5694 decl_initializer(t
, sec
, c
, first
, size_only
);
5696 } else if (size_only
) {
5697 /* just skip expression */
5699 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5703 else if (tok
== ')')
5708 /* currently, we always use constant expression for globals
5709 (may change for scripting case) */
5710 expr_type
= EXPR_CONST
;
5712 expr_type
= EXPR_ANY
;
5713 init_putv(t
, sec
, c
, 0, expr_type
);
5717 /* parse an initializer for type 't' if 'has_init' is true, and
5718 allocate space in local or global data space ('r' is either
5719 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5720 variable 'v' of scope 'scope' is declared before initializers are
5721 parsed. If 'v' is zero, then a reference to the new object is put
5722 in the value stack. */
5723 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5726 int size
, align
, addr
, data_offset
;
5728 ParseState saved_parse_state
;
5729 TokenString init_str
;
5732 size
= type_size(t
, &align
);
5733 /* If unknown size, we must evaluate it before
5734 evaluating initializers because
5735 initializers can generate global data too
5736 (e.g. string pointers or ISOC99 compound
5737 literals). It also simplifies local
5738 initializers handling */
5739 tok_str_new(&init_str
);
5742 error("unknown type size");
5743 /* get all init string */
5745 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5747 error("unexpected end of file in initializer");
5748 tok_str_add_tok(&init_str
);
5751 else if (tok
== '}') {
5758 tok_str_add(&init_str
, -1);
5759 tok_str_add(&init_str
, 0);
5762 save_parse_state(&saved_parse_state
);
5764 macro_ptr
= init_str
.str
;
5766 decl_initializer(t
, NULL
, 0, 1, 1);
5767 /* prepare second initializer parsing */
5768 macro_ptr
= init_str
.str
;
5771 /* if still unknown size, error */
5772 size
= type_size(t
, &align
);
5774 error("unknown type size");
5776 /* take into account specified alignment if bigger */
5777 if (ad
->aligned
> align
)
5778 align
= ad
->aligned
;
5779 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5781 if (do_bounds_check
&& (t
& VT_ARRAY
))
5783 #ifdef TCC_TARGET_IL
5784 /* XXX: ugly patch to allocate local variables for IL, just
5789 loc
= (loc
- size
) & -align
;
5792 /* handles bounds */
5793 /* XXX: currently, since we do only one pass, we cannot track
5794 '&' operators, so we add only arrays */
5795 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5797 /* add padding between regions */
5799 /* then add local bound info */
5800 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5801 *bounds_ptr
++ = addr
;
5802 *bounds_ptr
++ = size
;
5803 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5806 /* compute section */
5814 data_offset
= sec
->data_ptr
- sec
->data
;
5815 data_offset
= (data_offset
+ align
- 1) & -align
;
5817 /* very important to increment global pointer at this time
5818 because initializers themselves can create new initializers */
5819 data_offset
+= size
;
5820 /* handles bounds */
5821 if (do_bounds_check
) {
5823 /* first, we need to add at least one byte between each region */
5825 /* then add global bound info */
5826 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5827 /* XXX: add relocation */
5828 *bounds_ptr
++ = addr
+ (unsigned long)sec
->data
;
5829 *bounds_ptr
++ = size
;
5830 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5832 sec
->data_ptr
= sec
->data
+ data_offset
;
5838 /* local variable */
5839 sym_push(v
, t
, r
, addr
);
5841 if (scope
== VT_CONST
) {
5842 /* global scope: see if already defined */
5846 if (!is_compatible_types(sym
->t
, t
))
5847 error("incompatible types for redefinition of '%s'",
5848 get_tok_str(v
, NULL
));
5849 if (!(sym
->t
& VT_EXTERN
))
5850 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5851 sym
->t
&= ~VT_EXTERN
;
5854 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5856 put_extern_sym(sym
, sec
, addr
);
5860 /* push local reference */
5863 /* push global reference */
5864 vpush_ref(t
, sec
, addr
);
5868 decl_initializer(t
, sec
, addr
, 1, 0);
5869 /* restore parse state if needed */
5872 restore_parse_state(&saved_parse_state
);
5877 void put_func_debug(int t
)
5882 /* XXX: we put here a dummy type */
5883 snprintf(buf
, sizeof(buf
), "%s:%c1",
5884 funcname
, t
& VT_STATIC
? 'f' : 'F');
5885 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5891 /* not finished : try to put some local vars in registers */
5892 //#define CONFIG_REG_VARS
5894 #ifdef CONFIG_REG_VARS
5895 void add_var_ref(int t
)
5897 printf("%s:%d: &%s\n",
5898 file
->filename
, file
->line_num
,
5899 get_tok_str(t
, NULL
));
5902 /* first pass on a function with heuristic to extract variable usage
5903 and pointer references to local variables for register allocation */
5904 void analyse_function(void)
5911 /* any symbol coming after '&' is considered as being a
5912 variable whose reference is taken. It is highly unaccurate
5913 but it is difficult to do better without a complete parse */
5916 /* if '& number', then no need to examine next tokens */
5917 if (tok
== TOK_CINT
||
5919 tok
== TOK_CLLONG
||
5920 tok
== TOK_CULLONG
) {
5922 } else if (tok
>= TOK_UIDENT
) {
5923 /* if '& ident [' or '& ident ->', then ident address
5927 if (tok
!= '[' && tok
!= TOK_ARROW
)
5931 while (tok
!= '}' && tok
!= ';' &&
5932 !((tok
== ',' || tok
== ')') && level
== 0)) {
5933 if (tok
>= TOK_UIDENT
) {
5935 } else if (tok
== '(') {
5937 } else if (tok
== ')') {
5950 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5953 int t
, b
, v
, has_init
, r
;
5958 if (!parse_btype(&b
, &ad
)) {
5959 /* skip redundant ';' */
5960 /* XXX: find more elegant solution */
5965 /* special test for old K&R protos without explicit int
5966 type. Only accepted when defining global data */
5967 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5971 if (((b
& VT_BTYPE
) == VT_ENUM
||
5972 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5974 /* we accept no variable after */
5978 while (1) { /* iterate thru each declaration */
5979 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
5983 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5984 printf("type = '%s'\n", buf
);
5988 #ifdef CONFIG_REG_VARS
5989 TokenString func_str
;
5990 ParseState saved_parse_state
;
5995 error("cannot use local functions");
5997 expect("function definition");
5999 #ifdef CONFIG_REG_VARS
6000 /* parse all function code and record it */
6002 tok_str_new(&func_str
);
6008 error("unexpected end of file");
6009 tok_str_add_tok(&func_str
);
6014 } else if (t
== '}') {
6016 if (block_level
== 0)
6020 tok_str_add(&func_str
, -1);
6021 tok_str_add(&func_str
, 0);
6023 save_parse_state(&saved_parse_state
);
6025 macro_ptr
= func_str
.str
;
6030 /* compute text section */
6031 cur_text_section
= ad
.section
;
6032 if (!cur_text_section
)
6033 cur_text_section
= text_section
;
6034 ind
= (int)cur_text_section
->data_ptr
;
6035 funcname
= get_tok_str(v
, NULL
);
6038 /* if symbol is already defined, then put complete type */
6041 /* put function symbol */
6042 sym
= sym_push1(&global_stack
, v
, t
, 0);
6044 put_extern_sym(sym
, cur_text_section
,
6045 ind
- (int)cur_text_section
->data
);
6046 sym
->r
= VT_SYM
| VT_CONST
;
6047 /* put debug symbol */
6050 /* push a dummy symbol to enable local sym storage */
6051 sym_push1(&local_stack
, 0, 0, 0);
6055 #ifdef CONFIG_REG_VARS
6056 macro_ptr
= func_str
.str
;
6059 block(NULL
, NULL
, NULL
, NULL
, 0);
6062 cur_text_section
->data_ptr
= (unsigned char *)ind
;
6063 sym_pop(&label_stack
, NULL
); /* reset label stack */
6064 sym_pop(&local_stack
, NULL
); /* reset local stack */
6065 /* end of function */
6067 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6069 funcname
= ""; /* for safety */
6070 func_vt
= VT_VOID
; /* for safety */
6071 ind
= 0; /* for safety */
6073 #ifdef CONFIG_REG_VARS
6075 restore_parse_state(&saved_parse_state
);
6079 if (b
& VT_TYPEDEF
) {
6080 /* save typedefed type */
6081 /* XXX: test storage specifiers ? */
6082 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6083 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6084 /* external function definition */
6085 external_sym(v
, t
, 0);
6087 /* not lvalue if array */
6089 if (!(t
& VT_ARRAY
))
6090 r
|= lvalue_type(t
);
6091 if (b
& VT_EXTERN
) {
6092 /* external variable */
6093 external_sym(v
, t
, r
);
6099 has_init
= (tok
== '=');
6102 decl_initializer_alloc(t
, &ad
, r
,
6116 /* compile the C file opened in 'file'. Return non zero if errors. */
6117 static int tcc_compile(TCCState
*s
)
6124 include_stack_ptr
= include_stack
;
6125 ifdef_stack_ptr
= ifdef_stack
;
6128 anon_sym
= SYM_FIRST_ANOM
;
6130 /* file info: full path + filename */
6132 getcwd(buf
, sizeof(buf
));
6133 pstrcat(buf
, sizeof(buf
), "/");
6134 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6135 put_stabs(file
->filename
, N_SO
, 0, 0,
6136 (unsigned long)text_section
->data_ptr
);
6138 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6139 symbols can be safely used */
6140 put_elf_sym(symtab_section
, 0, 0,
6141 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6142 SHN_ABS
, file
->filename
);
6144 /* define common 'char *' type because it is often used internally
6145 for arrays and struct dereference */
6146 char_pointer_type
= mk_pointer(VT_BYTE
);
6147 /* define an old type function 'int func()' */
6149 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
6150 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6152 define_start
= define_stack
.top
;
6154 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6158 expect("declaration");
6160 /* end of translation unit info */
6162 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6165 /* reset define stack, but leave -Dsymbols (may be incorrect if
6166 they are undefined) */
6167 sym_pop(&define_stack
, define_start
);
6169 sym_pop(&global_stack
, NULL
);
6174 int tcc_compile_string(TCCState
*s
, const char *str
)
6176 BufferedFile bf1
, *bf
= &bf1
;
6179 /* init file structure */
6181 bf
->buf_ptr
= (char *)str
;
6182 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6183 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6187 ret
= tcc_compile(s
);
6189 /* currently, no need to close */
6193 /* define a symbol. A value can also be provided with the '=' operator */
6194 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6196 BufferedFile bf1
, *bf
= &bf1
;
6198 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6199 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6203 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6205 /* init file structure */
6207 bf
->buf_ptr
= bf
->buffer
;
6208 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6209 bf
->filename
[0] = '\0';
6213 include_stack_ptr
= include_stack
;
6215 /* parse with define parser */
6217 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6223 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6227 ts
= tok_alloc(sym
, 0);
6228 s
= sym_find1(&define_stack
, tok
);
6229 /* undefine symbol by putting an invalid name */
6231 sym_undef(&define_stack
, s
);
6234 static int put_elf_str(Section
*s
, const char *sym
)
6237 offset
= s
->data_ptr
- s
->data
;
6247 /* elf symbol hashing function */
6248 static unsigned long elf_hash(const unsigned char *name
)
6250 unsigned long h
= 0, g
;
6253 h
= (h
<< 4) + *name
++;
6262 /* return the symbol number */
6263 static int put_elf_sym(Section
*s
,
6264 unsigned long value
, unsigned long size
,
6265 int info
, int other
, int shndx
, const char *name
)
6267 int name_offset
, sym_index
;
6272 sym
= (Elf32_Sym
*)s
->data_ptr
;
6274 name_offset
= put_elf_str(s
->link
, name
);
6277 /* XXX: endianness */
6278 sym
->st_name
= name_offset
;
6279 sym
->st_value
= value
;
6280 sym
->st_size
= size
;
6281 sym
->st_info
= info
;
6282 sym
->st_other
= other
;
6283 sym
->st_shndx
= shndx
;
6284 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6287 /* only add global or weak symbols */
6288 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
6289 /* add another hashing entry */
6290 nbuckets
= ((int *)hs
->data
)[0];
6291 h
= elf_hash(name
) % nbuckets
;
6292 ((int *)hs
->data
)[2 + nbuckets
+ sym_index
] = ((int *)hs
->data
)[2 + h
];
6293 ((int *)hs
->data
)[2 + h
] = sym_index
;
6295 /* but still add room for all symbols */
6296 ((int *)hs
->data
)[1]++;
6297 hs
->data_ptr
+= sizeof(int);
6299 s
->data_ptr
+= sizeof(Elf32_Sym
);
6303 /* find global ELF symbol 'name' and return its index. Return 0 if not
6305 static int find_elf_sym(Section
*s
, const char *name
)
6309 int nbuckets
, sym_index
, h
;
6315 nbuckets
= ((int *)hs
->data
)[0];
6316 h
= elf_hash(name
) % nbuckets
;
6317 sym_index
= ((int *)hs
->data
)[2 + h
];
6318 while (sym_index
!= 0) {
6319 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6320 name1
= s
->link
->data
+ sym
->st_name
;
6321 if (!strcmp(name
, name1
))
6323 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6328 /* return elf symbol value or error */
6329 static unsigned long get_elf_sym_val(const char *name
)
6334 sym_index
= find_elf_sym(symtab_section
, name
);
6336 error("%s not defined", name
);
6337 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6338 return sym
->st_value
;
6341 /* add an elf symbol : check if it is already defined and patch
6342 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6343 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
6344 int info
, int sh_num
, const char *name
)
6347 int sym_bind
, sym_index
, sym_type
, esym_bind
;
6349 sym_bind
= ELF32_ST_BIND(info
);
6350 sym_type
= ELF32_ST_TYPE(info
);
6352 if (sym_bind
!= STB_LOCAL
) {
6353 /* we search global or weak symbols */
6354 sym_index
= find_elf_sym(s
, name
);
6357 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6358 if (esym
->st_shndx
!= SHN_UNDEF
) {
6359 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
6360 if (sh_num
== SHN_UNDEF
) {
6361 /* ignore adding of undefined symbol if the
6362 corresponding symbol is already defined */
6363 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
6364 /* global overrides weak, so patch */
6366 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
6367 /* weak is ignored if already global */
6370 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6371 sym_bind
, sh_num
, esym_bind
, esym
->st_shndx
);
6373 /* NOTE: we accept that two DLL define the same symbol */
6374 if (s
!= dynsymtab_section
)
6375 error("'%s' defined twice", name
);
6379 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6380 esym
->st_shndx
= sh_num
;
6381 esym
->st_value
= value
;
6382 esym
->st_size
= size
;
6386 sym_index
= put_elf_sym(s
, value
, size
,
6387 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6393 /* update sym->c so that it points to an external symbol in section
6394 'section' with value 'value' */
6395 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
)
6397 int sym_type
, sym_bind
, sh_num
, info
;
6402 sh_num
= section
->sh_num
;
6406 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6407 sym_type
= STT_FUNC
;
6409 sym_type
= STT_OBJECT
;
6410 if (sym
->t
& VT_STATIC
)
6411 sym_bind
= STB_LOCAL
;
6413 sym_bind
= STB_GLOBAL
;
6414 name
= get_tok_str(sym
->v
, NULL
);
6415 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6416 sym
->c
= add_elf_sym(symtab_section
, value
, 0, info
, sh_num
, name
);
6418 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6419 esym
->st_value
= value
;
6420 esym
->st_shndx
= sh_num
;
6424 /* put relocation */
6425 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
6426 int type
, int symbol
)
6434 /* if no relocation section, create it */
6435 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6436 /* if the symtab is allocated, then we consider the relocation
6438 sr
= new_section(buf
, SHT_REL
, symtab
->sh_flags
);
6439 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6441 sr
->sh_info
= s
->sh_num
;
6444 rel
= (Elf32_Rel
*)sr
->data_ptr
;
6445 /* XXX: endianness */
6446 rel
->r_offset
= offset
;
6447 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6448 sr
->data_ptr
+= sizeof(Elf32_Rel
);
6451 /* put stab debug information */
6454 unsigned long n_strx
; /* index into string table of name */
6455 unsigned char n_type
; /* type of symbol */
6456 unsigned char n_other
; /* misc info (usually empty) */
6457 unsigned short n_desc
; /* description field */
6458 unsigned long n_value
; /* value of symbol */
6461 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
6465 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
6467 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6472 sym
->n_other
= other
;
6474 sym
->n_value
= value
;
6476 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
6479 static void put_stabn(int type
, int other
, int desc
, int value
)
6481 put_stabs(NULL
, type
, other
, desc
, value
);
6484 static void put_stabd(int type
, int other
, int desc
)
6486 put_stabs(NULL
, type
, other
, desc
, 0);
6489 /* In an ELF file symbol table, the local symbols must appear below
6490 the global and weak ones. Since TCC cannot sort it while generating
6491 the code, we must do it after. All the relocation tables are also
6492 modified to take into account the symbol table sorting */
6493 static void sort_syms(Section
*s
)
6495 int *old_to_new_syms
;
6496 Elf32_Sym
*new_syms
;
6501 int type
, sym_index
;
6503 nb_syms
= (s
->data_ptr
- s
->data
) / sizeof(Elf32_Sym
);
6504 new_syms
= malloc(nb_syms
* sizeof(Elf32_Sym
));
6506 error("memory full");
6507 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
6508 if (!old_to_new_syms
)
6509 error("memory full");
6510 /* first pass for local symbols */
6511 p
= (Elf32_Sym
*)s
->data
;
6513 for(i
= 0; i
< nb_syms
; i
++) {
6514 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
6515 old_to_new_syms
[i
] = q
- new_syms
;
6520 /* save the number of local symbols in section header */
6521 s
->sh_info
= q
- new_syms
;
6523 /* then second pass for non local symbols */
6524 p
= (Elf32_Sym
*)s
->data
;
6525 for(i
= 0; i
< nb_syms
; i
++) {
6526 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
6527 old_to_new_syms
[i
] = q
- new_syms
;
6533 /* we copy the new symbols to the old */
6534 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
6537 /* now we modify all the relocations */
6538 for(i
= 1; i
< nb_sections
; i
++) {
6540 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
6541 for(rel
= (Elf32_Rel
*)sr
->data
;
6542 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6544 sym_index
= ELF32_R_SYM(rel
->r_info
);
6545 type
= ELF32_R_TYPE(rel
->r_info
);
6546 sym_index
= old_to_new_syms
[sym_index
];
6547 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
6552 free(old_to_new_syms
);
6555 /* relocate common symbols in the .bss section */
6556 static void relocate_common_syms(void)
6559 unsigned long offset
, align
;
6561 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6562 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6564 if (sym
->st_shndx
== SHN_COMMON
) {
6566 align
= sym
->st_value
;
6567 offset
= bss_section
->data_ptr
- bss_section
->data
;
6568 offset
= (offset
+ align
- 1) & -align
;
6569 sym
->st_value
= offset
;
6570 sym
->st_shndx
= bss_section
->sh_num
;
6571 offset
+= sym
->st_size
;
6572 bss_section
->data_ptr
= bss_section
->data
+ offset
;
6577 static void *resolve_sym(const char *sym
)
6579 #ifdef CONFIG_TCC_BCHECK
6580 if (do_bounds_check
) {
6582 ptr
= bound_resolve_sym(sym
);
6587 return dlsym(NULL
, sym
);
6590 /* relocate symbol table, resolve undefined symbols if do_resolve is
6591 true and output error if undefined symbol. */
6592 static void relocate_syms(int do_resolve
)
6594 Elf32_Sym
*sym
, *esym
;
6595 int sym_bind
, sh_num
, sym_index
;
6599 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6600 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6602 sh_num
= sym
->st_shndx
;
6603 if (sh_num
== SHN_UNDEF
) {
6604 name
= strtab_section
->data
+ sym
->st_name
;
6606 name
= symtab_section
->link
->data
+ sym
->st_name
;
6607 addr
= (unsigned long)resolve_sym(name
);
6609 sym
->st_value
= addr
;
6612 } else if (dynsym
) {
6613 /* if dynamic symbol exist, then use it */
6614 sym_index
= find_elf_sym(dynsym
, name
);
6616 esym
= &((Elf32_Sym
*)dynsym
->data
)[sym_index
];
6617 sym
->st_value
= esym
->st_value
;
6621 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
6623 if (!strcmp(name
, "_fp_hw"))
6625 /* only weak symbols are accepted to be undefined. Their
6627 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
6628 if (sym_bind
== STB_WEAK
) {
6631 error("undefined symbol '%s'", name
);
6633 } else if (sh_num
< SHN_LORESERVE
) {
6634 /* add section base */
6635 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
6641 /* elf relocation, CPU dependant */
6642 static void elf_reloc(unsigned char *ptr
,
6643 unsigned long addr
, unsigned long val
, int type
,
6652 *(int *)ptr
+= val
- addr
;
6654 case R_386_GLOB_DAT
:
6655 case R_386_JMP_SLOT
:
6659 *(int *)ptr
+= got
->sh_addr
- addr
;
6662 *(int *)ptr
+= val
- got
->sh_addr
;
6665 /* we load the got offset */
6666 *(int *)ptr
+= got_offsets
[sym_index
];
6672 /* relocate a given section */
6673 static void relocate_section(Section
*s
)
6678 int type
, sym_index
;
6683 for(rel
= (Elf32_Rel
*)sr
->data
;
6684 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6686 ptr
= s
->data
+ rel
->r_offset
;
6688 sym_index
= ELF32_R_SYM(rel
->r_info
);
6689 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6690 val
= sym
->st_value
;
6691 type
= ELF32_R_TYPE(rel
->r_info
);
6692 elf_reloc(ptr
, s
->sh_addr
+ rel
->r_offset
, val
, type
, sym_index
);
6696 /* relocate relocation table in 'sr' */
6697 static void relocate_rel(Section
*sr
)
6702 s
= sections
[sr
->sh_info
];
6703 for(rel
= (Elf32_Rel
*)sr
->data
;
6704 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6706 rel
->r_offset
+= s
->sh_addr
;
6710 static void put_got_offset(int index
, unsigned long val
)
6715 if (index
>= nb_got_offsets
) {
6716 /* find immediately bigger power of 2 and reallocate array */
6720 tab
= realloc(got_offsets
, n
* sizeof(unsigned long));
6722 error("memory full");
6724 memset(got_offsets
+ nb_got_offsets
, 0,
6725 (n
- nb_got_offsets
) * sizeof(unsigned long));
6728 got_offsets
[index
] = val
;
6731 /* XXX: suppress that */
6732 static void put32(unsigned char *p
, unsigned int val
)
6740 static void build_got(void)
6742 /* if no got, then create it */
6743 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6744 got
->sh_entsize
= 4;
6745 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
6746 got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
6747 /* keep space for _DYNAMIC pointer, if present */
6750 /* two dummy got entries */
6751 put32(got
->data_ptr
, 0);
6753 put32(got
->data_ptr
, 0);
6757 /* put a got entry corresponding to a symbol in symtab_section. 'size'
6758 and 'info' can be modifed if more precise info comes from the DLL */
6759 static void put_got_entry(int reloc_type
, unsigned long size
, int info
,
6765 unsigned long offset
;
6770 /* if a got entry already exists for that symbol, no need to add one */
6771 if (sym_index
< nb_got_offsets
&&
6772 got_offsets
[sym_index
] != 0)
6775 put_got_offset(sym_index
, got
->data_ptr
- got
->data
);
6778 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6779 name
= symtab_section
->link
->data
+ sym
->st_name
;
6780 offset
= sym
->st_value
;
6781 /* NOTE: we put temporarily the got offset */
6782 if (reloc_type
== R_386_JMP_SLOT
) {
6784 offset
= got
->data_ptr
- got
->data
;
6786 index
= put_elf_sym(dynsym
, offset
,
6787 size
, info
, 0, sym
->st_shndx
, name
);
6788 /* put a got entry */
6789 put_elf_reloc(dynsym
, got
,
6790 got
->data_ptr
- got
->data
,
6793 put32(got
->data_ptr
, 0);
6797 /* build GOT and PLT entries */
6798 static void build_got_entries(void)
6800 Section
*s
, *symtab
;
6803 int i
, type
, reloc_type
, sym_index
;
6805 for(i
= 1; i
< nb_sections
; i
++) {
6807 if (s
->sh_type
!= SHT_REL
)
6809 /* no need to handle got relocations */
6810 if (s
->link
!= symtab_section
)
6813 for(rel
= (Elf32_Rel
*)s
->data
;
6814 rel
< (Elf32_Rel
*)s
->data_ptr
;
6816 type
= ELF32_R_TYPE(rel
->r_info
);
6824 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
6825 sym_index
= ELF32_R_SYM(rel
->r_info
);
6826 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6827 /* look at the symbol got offset. If none, then add one */
6828 if (type
== R_386_GOT32
)
6829 reloc_type
= R_386_GLOB_DAT
;
6831 reloc_type
= R_386_JMP_SLOT
;
6832 put_got_entry(reloc_type
, sym
->st_size
, sym
->st_info
,
6843 static Section
*new_section_hash(const char *name
, int sh_flags
,
6844 int nb_buckets
, Section
*symtab
)
6847 hash
= new_section(name
, SHT_HASH
, sh_flags
);
6848 ((int *)hash
->data
)[0] = nb_buckets
;
6849 ((int *)hash
->data
)[1] = 1;
6850 hash
->sh_entsize
= sizeof(int);
6851 hash
->data_ptr
+= (2 + nb_buckets
+ 1) * sizeof(int);
6852 symtab
->hash
= hash
;
6853 hash
->link
= symtab
;
6857 /* put dynamic tag */
6858 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
6861 dyn
= (Elf32_Dyn
*)dynamic
->data_ptr
;
6863 dyn
->d_un
.d_val
= val
;
6864 dynamic
->data_ptr
+= sizeof(Elf32_Dyn
);
6867 /* add tcc runtime libraries */
6868 static void tcc_add_runtime(TCCState
*s1
)
6870 tcc_add_file(s1
, CONFIG_TCC_PREFIX
"/lib/tcc/libtcc1.o");
6873 /* add dynamic sections so that the executable is dynamically linked */
6874 static char elf_interp
[] = "/lib/ld-linux.so.2";
6876 #define ELF_START_ADDR 0x08048000
6877 #define ELF_PAGE_SIZE 0x1000
6879 /* output an ELF file */
6880 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6881 /* XXX: suppress unneeded sections */
6882 int tcc_output_file(TCCState
*s1
, const char *filename
)
6888 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
6890 Section
*strsec
, *s
;
6891 Elf32_Shdr shdr
, *sh
;
6892 Elf32_Phdr
*phdr
, *ph
;
6893 Section
*interp
, *plt
, *dynamic
, *dynstr
, *hash
;
6894 unsigned char *saved_dynamic_data_ptr
;
6896 int type
, file_type
;
6897 unsigned long rel_addr
, rel_size
;
6899 file_type
= s1
->output_type
;
6901 /* add libc crtn object */
6902 if (file_type
!= TCC_OUTPUT_OBJ
) {
6903 tcc_add_runtime(s1
);
6904 tcc_add_library(s1
, "c");
6905 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
6913 plt
= NULL
; /* avoid warning */
6914 hash
= NULL
; /* avoid warning */
6915 dynstr
= NULL
; /* avoid warning */
6916 saved_dynamic_data_ptr
= NULL
; /* avoid warning */
6918 if (file_type
!= TCC_OUTPUT_OBJ
) {
6920 relocate_common_syms();
6924 int sym_index
, index
;
6927 if (file_type
== TCC_OUTPUT_EXE
) {
6928 /* add interpreter section only if executable */
6929 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
6930 interp
->sh_addralign
= 1;
6931 strcpy(interp
->data_ptr
, elf_interp
);
6932 interp
->data_ptr
+= sizeof(elf_interp
);
6935 /* add dynamic symbol table */
6936 dynsym
= new_section(".dynsym", SHT_DYNSYM
, SHF_ALLOC
);
6937 dynsym
->sh_entsize
= sizeof(Elf32_Sym
);
6938 dynstr
= new_section(".dynstr", SHT_STRTAB
, SHF_ALLOC
);
6939 put_elf_str(dynstr
, "");
6940 dynsym
->link
= dynstr
;
6941 put_elf_sym(dynsym
, 0, 0, 0, 0, 0, NULL
);
6944 hash
= new_section_hash(".hash", SHF_ALLOC
,
6945 ELF_DYNSYM_HASH_SIZE
, dynsym
);
6947 /* add dynamic section */
6948 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
6949 SHF_ALLOC
| SHF_WRITE
);
6950 dynamic
->link
= dynstr
;
6951 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
6954 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6955 plt
->sh_entsize
= 4;
6957 /* scan for undefined symbols and see if they are in the
6958 dynamic symbols. If a symbol STT_FUNC is found, then we
6959 add it in the PLT. If a symbol STT_OBJECT is found, we
6960 add it in the .bss section with a suitable relocation */
6961 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6962 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6964 if (sym
->st_shndx
== SHN_UNDEF
) {
6965 name
= symtab_section
->link
->data
+ sym
->st_name
;
6966 sym_index
= find_elf_sym(dynsymtab_section
, name
);
6968 esym
= &((Elf32_Sym
*)dynsymtab_section
->data
)[sym_index
];
6969 type
= ELF32_ST_TYPE(esym
->st_info
);
6970 if (type
== STT_FUNC
) {
6971 put_got_entry(R_386_JMP_SLOT
, esym
->st_size
,
6973 sym
- (Elf32_Sym
*)symtab_section
->data
);
6974 } else if (type
== STT_OBJECT
) {
6975 unsigned long offset
;
6976 offset
= bss_section
->data_ptr
- bss_section
->data
;
6977 /* XXX: which alignment ? */
6978 offset
= (offset
+ 8 - 1) & -8;
6979 index
= put_elf_sym(dynsym
, offset
, esym
->st_size
,
6981 bss_section
->sh_num
, name
);
6982 put_elf_reloc(dynsym
, bss_section
,
6983 offset
, R_386_COPY
, index
);
6984 offset
+= esym
->st_size
;
6985 bss_section
->data_ptr
= bss_section
->data
+ offset
;
6988 /* STT_NOTYPE or STB_WEAK undefined symbols
6990 /* XXX: STT_NOTYPE is only used to exclude the
6991 unreferenced '_fp_hw' symbol. need a better
6993 if (ELF32_ST_TYPE(sym
->st_info
) == STT_NOTYPE
||
6994 ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
) {
6996 error("undefined symbol '%s'", name
);
7002 /* now look at unresolved dynamic symbols and export
7003 corresponding symbol */
7004 for(sym
= (Elf32_Sym
*)dynsymtab_section
->data
+ 1;
7005 sym
< (Elf32_Sym
*)dynsymtab_section
->data_ptr
;
7007 if (sym
->st_shndx
== SHN_UNDEF
) {
7008 name
= dynsymtab_section
->link
->data
+ sym
->st_name
;
7009 sym_index
= find_elf_sym(symtab_section
, name
);
7012 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
) {
7013 /* weak symbols can stay undefined */
7015 warning("undefined dynamic symbol '%s'", name
);
7021 build_got_entries();
7023 /* update PLT/GOT sizes so that we can allocate their space */
7024 plt
->data_ptr
+= 16 * (nb_plt_entries
+ 1);
7026 /* add a list of needed dlls */
7027 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7028 DLLReference
*dllref
= loaded_dlls
[i
];
7029 if (dllref
->level
== 0)
7030 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
7033 /* add necessary space for other entries */
7034 saved_dynamic_data_ptr
= dynamic
->data_ptr
;
7035 dynamic
->data_ptr
+= 8 * 9;
7037 /* still need to build got entries in case of static link */
7038 build_got_entries();
7042 memset(&ehdr
, 0, sizeof(ehdr
));
7044 /* we add a section for symbols */
7045 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
7046 put_elf_str(strsec
, "");
7048 /* compute number of sections */
7049 shnum
= nb_sections
;
7051 /* this array is used to reorder sections in the output file */
7052 section_order
= malloc(sizeof(int) * shnum
);
7054 error("memory full");
7055 section_order
[0] = 0;
7058 /* compute number of program headers */
7061 case TCC_OUTPUT_OBJ
:
7064 case TCC_OUTPUT_EXE
:
7070 case TCC_OUTPUT_DLL
:
7075 /* allocate strings for section names */
7076 for(i
= 1; i
< nb_sections
; i
++) {
7078 s
->sh_name
= put_elf_str(strsec
, s
->name
);
7079 s
->sh_size
= s
->data_ptr
- s
->data
;
7082 /* allocate program segment headers */
7083 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
7085 error("memory full");
7086 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
7088 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7090 /* compute section to program header mapping */
7091 if (file_type
== TCC_OUTPUT_DLL
)
7094 addr
= ELF_START_ADDR
;
7096 /* dynamic relocation table information, for .dynamic section */
7100 /* compute address after headers */
7101 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
7103 /* leave one program header for the program interpreter */
7108 for(j
= 0; j
< 2; j
++) {
7109 ph
->p_type
= PT_LOAD
;
7111 ph
->p_flags
= PF_R
| PF_X
;
7113 ph
->p_flags
= PF_R
| PF_W
;
7114 ph
->p_align
= ELF_PAGE_SIZE
;
7116 /* we do the following ordering: interp, symbol tables,
7117 relocations, progbits, nobits */
7118 /* XXX: do faster and simpler sorting */
7119 for(k
= 0; k
< 5; k
++) {
7120 for(i
= 1; i
< nb_sections
; i
++) {
7122 /* compute if section should be included */
7124 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7128 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7129 (SHF_ALLOC
| SHF_WRITE
))
7135 } else if (s
->sh_type
== SHT_DYNSYM
||
7136 s
->sh_type
== SHT_STRTAB
||
7137 s
->sh_type
== SHT_HASH
) {
7140 } else if (s
->sh_type
== SHT_REL
) {
7143 } else if (s
->sh_type
== SHT_NOBITS
) {
7150 section_order
[sh_order_index
++] = i
;
7152 /* section matches: we align it and add its size */
7154 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7155 ~(s
->sh_addralign
- 1);
7156 s
->sh_offset
= file_offset
;
7157 addr
+= file_offset
- tmp
;
7160 /* update program header infos */
7161 if (ph
->p_offset
== 0) {
7162 ph
->p_offset
= file_offset
;
7164 ph
->p_paddr
= ph
->p_vaddr
;
7166 /* update dynamic relocation infos */
7167 if (s
->sh_type
== SHT_REL
) {
7170 rel_size
+= s
->sh_size
;
7173 if (s
->sh_type
!= SHT_NOBITS
)
7174 file_offset
+= s
->sh_size
;
7177 ph
->p_filesz
= file_offset
- ph
->p_offset
;
7178 ph
->p_memsz
= addr
- ph
->p_vaddr
;
7182 /* if interpreter, then add corresponing program header */
7186 ph
->p_type
= PT_INTERP
;
7187 ph
->p_offset
= interp
->sh_offset
;
7188 ph
->p_vaddr
= interp
->sh_addr
;
7189 ph
->p_paddr
= ph
->p_vaddr
;
7190 ph
->p_filesz
= interp
->sh_size
;
7191 ph
->p_memsz
= interp
->sh_size
;
7193 ph
->p_align
= interp
->sh_addralign
;
7196 /* if dynamic section, then add corresponing program header */
7201 ph
= &phdr
[phnum
- 1];
7203 ph
->p_type
= PT_DYNAMIC
;
7204 ph
->p_offset
= dynamic
->sh_offset
;
7205 ph
->p_vaddr
= dynamic
->sh_addr
;
7206 ph
->p_paddr
= ph
->p_vaddr
;
7207 ph
->p_filesz
= dynamic
->sh_size
;
7208 ph
->p_memsz
= dynamic
->sh_size
;
7209 ph
->p_flags
= PF_R
| PF_W
;
7210 ph
->p_align
= dynamic
->sh_addralign
;
7212 /* put GOT dynamic section address */
7213 put32(got
->data
, dynamic
->sh_addr
);
7215 /* compute the PLT */
7216 plt
->data_ptr
= plt
->data
;
7218 /* first plt entry */
7220 p
[0] = 0xff; /* pushl got + 4 */
7222 put32(p
+ 2, got
->sh_addr
+ 4);
7223 p
[6] = 0xff; /* jmp *(got + 8) */
7225 put32(p
+ 8, got
->sh_addr
+ 8);
7226 plt
->data_ptr
+= 16;
7228 /* relocation symbols in .dynsym and build PLT. */
7230 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
7231 sym
< (Elf32_Sym
*)dynsym
->data_ptr
;
7233 type
= ELF32_ST_TYPE(sym
->st_info
);
7234 if (sym
->st_shndx
== SHN_UNDEF
) {
7235 if (type
== STT_FUNC
) {
7236 /* one more entry in PLT */
7238 p
[0] = 0xff; /* jmp *(got + x) */
7240 put32(p
+ 2, got
->sh_addr
+ sym
->st_value
);
7241 p
[6] = 0x68; /* push $xxx */
7242 put32(p
+ 7, plt_offset
);
7243 p
[11] = 0xe9; /* jmp plt_start */
7244 put32(p
+ 12, -(plt
->data_ptr
+ 16 - plt
->data
));
7246 /* patch symbol value to point to plt */
7247 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
7250 plt
->data_ptr
+= 16;
7252 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
7253 /* do symbol relocation */
7254 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
7257 /* put dynamic section entries */
7259 dynamic
->data_ptr
= saved_dynamic_data_ptr
;
7260 put_dt(dynamic
, DT_HASH
, hash
->sh_addr
);
7261 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
7262 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
7263 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_ptr
- dynstr
->data
);
7264 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
7265 put_dt(dynamic
, DT_REL
, rel_addr
);
7266 put_dt(dynamic
, DT_RELSZ
, rel_size
);
7267 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
7268 put_dt(dynamic
, DT_NULL
, 0);
7271 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
7272 ehdr
.e_phnum
= phnum
;
7273 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
7276 /* all other sections come after */
7277 for(i
= 1; i
< nb_sections
; i
++) {
7279 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
7281 section_order
[sh_order_index
++] = i
;
7283 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7284 ~(s
->sh_addralign
- 1);
7285 s
->sh_offset
= file_offset
;
7286 if (s
->sh_type
!= SHT_NOBITS
)
7287 file_offset
+= s
->sh_size
;
7290 /* if building executable or DLL, then relocate each section
7291 except the GOT which is already relocated */
7292 if (file_type
!= TCC_OUTPUT_OBJ
) {
7295 /* relocate sections */
7296 /* XXX: ignore sections with allocated relocations ? */
7297 for(i
= 1; i
< nb_sections
; i
++) {
7299 if ((s
->sh_flags
& SHF_ALLOC
)
7300 && s
->reloc
&& s
!= got
)
7301 relocate_section(s
);
7304 /* relocate relocation entries */
7305 for(i
= 1; i
< nb_sections
; i
++) {
7307 if ((s
->sh_flags
& SHF_ALLOC
) &&
7308 s
->sh_type
== SHT_REL
) {
7313 /* get entry point address */
7314 ehdr
.e_entry
= get_elf_sym_val("_start");
7317 sort_syms(symtab_section
);
7320 file_offset
= (file_offset
+ 3) & -4;
7323 ehdr
.e_ident
[0] = ELFMAG0
;
7324 ehdr
.e_ident
[1] = ELFMAG1
;
7325 ehdr
.e_ident
[2] = ELFMAG2
;
7326 ehdr
.e_ident
[3] = ELFMAG3
;
7327 ehdr
.e_ident
[4] = ELFCLASS32
;
7328 ehdr
.e_ident
[5] = ELFDATA2LSB
;
7329 ehdr
.e_ident
[6] = EV_CURRENT
;
7332 case TCC_OUTPUT_EXE
:
7333 ehdr
.e_type
= ET_EXEC
;
7335 case TCC_OUTPUT_DLL
:
7336 ehdr
.e_type
= ET_DYN
;
7338 case TCC_OUTPUT_OBJ
:
7339 ehdr
.e_type
= ET_REL
;
7342 ehdr
.e_machine
= EM_386
;
7343 ehdr
.e_version
= EV_CURRENT
;
7344 ehdr
.e_shoff
= file_offset
;
7345 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
7346 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
7347 ehdr
.e_shnum
= shnum
;
7348 ehdr
.e_shstrndx
= shnum
- 1;
7350 /* write elf file */
7351 if (file_type
== TCC_OUTPUT_OBJ
)
7355 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
7357 error("could not write '%s'", filename
);
7359 f
= fdopen(fd
, "w");
7360 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
7361 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
7362 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7363 for(i
=1;i
<nb_sections
;i
++) {
7364 s
= sections
[section_order
[i
]];
7365 if (s
->sh_type
!= SHT_NOBITS
) {
7366 while (offset
< s
->sh_offset
) {
7370 size
= s
->data_ptr
- s
->data
;
7371 fwrite(s
->data
, 1, size
, f
);
7375 while (offset
< ehdr
.e_shoff
) {
7380 /* output section headers */
7381 for(i
=0;i
<nb_sections
;i
++) {
7383 memset(sh
, 0, sizeof(Elf32_Shdr
));
7386 sh
->sh_name
= s
->sh_name
;
7387 sh
->sh_type
= s
->sh_type
;
7388 sh
->sh_flags
= s
->sh_flags
;
7389 sh
->sh_entsize
= s
->sh_entsize
;
7390 sh
->sh_info
= s
->sh_info
;
7392 sh
->sh_link
= s
->link
->sh_num
;
7393 sh
->sh_addralign
= s
->sh_addralign
;
7394 sh
->sh_addr
= s
->sh_addr
;
7395 sh
->sh_offset
= s
->sh_offset
;
7396 sh
->sh_size
= s
->sh_size
;
7398 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
7402 free(section_order
);
7407 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
7411 data
= malloc(size
);
7413 error("memory full");
7414 lseek(fd
, file_offset
, SEEK_SET
);
7415 read(fd
, data
, size
);
7419 typedef struct SectionMergeInfo
{
7420 Section
*s
; /* corresponding existing section */
7421 unsigned long offset
; /* offset of the new section in the existing section */
7422 int new_section
; /* true if section 's' was added */
7425 /* load an object file and merge it with current files */
7426 /* XXX: handle correctly stab (debug) info */
7427 static int tcc_load_object_file(TCCState
*s1
,
7428 int fd
, unsigned long file_offset
)
7431 Elf32_Shdr
*shdr
, *sh
;
7432 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
;
7433 unsigned char *strsec
, *strtab
;
7434 int *old_to_new_syms
;
7435 char *sh_name
, *name
;
7436 SectionMergeInfo
*sm_table
, *sm
;
7437 Elf32_Sym
*sym
, *symtab
;
7441 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
7443 if (ehdr
.e_ident
[0] != ELFMAG0
||
7444 ehdr
.e_ident
[1] != ELFMAG1
||
7445 ehdr
.e_ident
[2] != ELFMAG2
||
7446 ehdr
.e_ident
[3] != ELFMAG3
)
7448 /* test if object file */
7449 if (ehdr
.e_type
!= ET_REL
)
7451 /* test CPU specific stuff */
7452 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7453 ehdr
.e_machine
!= EM_386
) {
7455 error("invalid object file");
7458 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
7459 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7460 sm_table
= malloc(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7462 error("memory full");
7463 memset(sm_table
, 0, sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7465 /* load section names */
7466 sh
= &shdr
[ehdr
.e_shstrndx
];
7467 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7469 /* load symtab and strtab */
7473 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7475 if (sh
->sh_type
== SHT_SYMTAB
) {
7477 error("object must contain only one symtab");
7478 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7479 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7480 sm_table
[i
].s
= symtab_section
;
7482 /* now load strtab */
7483 sh
= &shdr
[sh
->sh_link
];
7484 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7488 /* now examine each section and try to merge its content with the
7490 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7491 /* no need to examine section name strtab */
7492 if (i
== ehdr
.e_shstrndx
)
7495 sh_name
= strsec
+ sh
->sh_name
;
7496 /* ignore sections types we do not handle */
7497 if (sh
->sh_type
!= SHT_PROGBITS
&&
7498 sh
->sh_type
!= SHT_REL
&&
7499 sh
->sh_type
!= SHT_NOBITS
)
7501 if (sh
->sh_addralign
< 1)
7502 sh
->sh_addralign
= 1;
7503 /* find corresponding section, if any */
7504 for(j
= 1; j
< nb_sections
;j
++) {
7506 if (!strcmp(s
->name
, sh_name
))
7509 /* not found: create new section */
7510 s
= new_section(sh_name
, sh
->sh_type
, sh
->sh_flags
);
7511 /* take as much info as possible from the section. sh_link and
7512 sh_info will be updated later */
7513 s
->sh_addralign
= sh
->sh_addralign
;
7514 s
->sh_entsize
= sh
->sh_entsize
;
7515 sm_table
[i
].new_section
= 1;
7517 if (sh
->sh_type
!= s
->sh_type
)
7520 /* align start of section */
7521 offset
= s
->data_ptr
- s
->data
;
7522 size
= sh
->sh_addralign
- 1;
7523 offset
= (offset
+ size
) & ~size
;
7524 if (sh
->sh_addralign
> s
->sh_addralign
)
7525 s
->sh_addralign
= sh
->sh_addralign
;
7526 s
->data_ptr
= s
->data
+ offset
;
7527 sm_table
[i
].offset
= offset
;
7529 /* concatenate sections */
7531 if (sh
->sh_type
!= SHT_NOBITS
) {
7532 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
7533 read(fd
, s
->data_ptr
, size
);
7535 s
->data_ptr
+= size
;
7538 /* second short pass to update sh_link and sh_info fields of new
7541 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7543 if (!s
|| !sm_table
[i
].new_section
)
7546 if (sh
->sh_link
> 0)
7547 s
->link
= sm_table
[sh
->sh_link
].s
;
7548 if (sh
->sh_type
== SHT_REL
) {
7549 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
7550 /* update backward link */
7551 sections
[s
->sh_info
]->reloc
= s
;
7555 /* resolve symbols */
7556 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
7557 if (!old_to_new_syms
)
7558 error("memory full");
7559 memset(old_to_new_syms
, 0, nb_syms
* sizeof(int));
7561 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
7562 if (sym
->st_shndx
!= SHN_UNDEF
&&
7563 sym
->st_shndx
< SHN_LORESERVE
) {
7564 sm
= &sm_table
[sym
->st_shndx
];
7565 /* if no corresponding section added, no need to add symbol */
7568 /* convert section number */
7569 sym
->st_shndx
= sm
->s
->sh_num
;
7571 sym
->st_value
+= sm
->offset
;
7574 name
= strtab
+ sym
->st_name
;
7575 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
7576 sym
->st_info
, sym
->st_shndx
, name
);
7577 old_to_new_syms
[i
] = sym_index
;
7580 /* third pass to patch relocation entries */
7581 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7586 offset
= sm_table
[i
].offset
;
7587 switch(s
->sh_type
) {
7589 /* take relocation offset information */
7590 offseti
= sm_table
[sh
->sh_info
].offset
;
7591 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
7592 rel
< (Elf32_Rel
*)s
->data_ptr
;
7596 /* convert symbol index */
7597 type
= ELF32_R_TYPE(rel
->r_info
);
7598 sym_index
= ELF32_R_SYM(rel
->r_info
);
7599 /* NOTE: only one symtab assumed */
7600 if (sym_index
>= nb_syms
)
7602 sym_index
= old_to_new_syms
[sym_index
];
7605 error("Invalid relocation entry");
7607 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
7608 /* offset the relocation offset */
7609 rel
->r_offset
+= offseti
;
7618 free(old_to_new_syms
);
7624 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7626 typedef struct ArchiveHeader
{
7627 char ar_name
[16]; /* name of this member */
7628 char ar_date
[12]; /* file mtime */
7629 char ar_uid
[6]; /* owner uid; printed as decimal */
7630 char ar_gid
[6]; /* owner gid; printed as decimal */
7631 char ar_mode
[8]; /* file mode, printed as octal */
7632 char ar_size
[10]; /* file size, printed as decimal */
7633 char ar_fmag
[2]; /* should contain ARFMAG */
7636 /* load a '.a' file */
7637 static int tcc_load_archive(TCCState
*s1
, int fd
)
7644 unsigned long file_offset
;
7646 /* skip magic which was already checked */
7647 read(fd
, magic
, sizeof(magic
));
7650 len
= read(fd
, &hdr
, sizeof(hdr
));
7653 if (len
!= sizeof(hdr
))
7654 error("invalid archive");
7655 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
7656 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
7657 size
= strtol(ar_size
, NULL
, 0);
7658 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
7659 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
7660 if (ar_name
[i
] != ' ')
7663 ar_name
[i
+ 1] = '\0';
7664 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7665 file_offset
= lseek(fd
, 0, SEEK_CUR
);
7666 if (!strcmp(ar_name
, "/") ||
7667 !strcmp(ar_name
, "//") ||
7668 !strcmp(ar_name
, "__.SYMDEF") ||
7669 !strcmp(ar_name
, "__.SYMDEF/") ||
7670 !strcmp(ar_name
, "ARFILENAMES/")) {
7671 /* skip symbol table or archive names */
7673 tcc_load_object_file(s1
, fd
, file_offset
);
7676 size
= (size
+ 1) & ~1;
7677 lseek(fd
, file_offset
+ size
, SEEK_SET
);
7682 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
7683 is referenced by the user (so it should be added as DT_NEEDED in
7684 the generated ELF file) */
7685 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
7688 Elf32_Shdr
*shdr
, *sh
, *sh1
;
7689 int i
, nb_syms
, nb_dts
, sym_bind
;
7690 Elf32_Sym
*sym
, *dynsym
;
7691 Elf32_Dyn
*dt
, *dynamic
;
7692 unsigned char *dynstr
;
7693 const char *name
, *soname
, *p
;
7694 DLLReference
*dllref
;
7696 read(fd
, &ehdr
, sizeof(ehdr
));
7698 /* test CPU specific stuff */
7699 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7700 ehdr
.e_machine
!= EM_386
)
7701 error("bad architecture");
7704 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7706 /* load dynamic section and dynamic symbols */
7710 dynsym
= NULL
; /* avoid warning */
7711 dynstr
= NULL
; /* avoid warning */
7712 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
7713 switch(sh
->sh_type
) {
7715 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
7716 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
7719 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7720 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
7721 sh1
= &shdr
[sh
->sh_link
];
7722 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
7729 /* compute the real library name */
7731 p
= strrchr(soname
, '/');
7735 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
7736 if (dt
->d_tag
== DT_SONAME
) {
7737 soname
= dynstr
+ dt
->d_un
.d_val
;
7741 /* if the dll is already loaded, do not load it */
7742 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7743 dllref
= loaded_dlls
[i
];
7744 if (!strcmp(soname
, dllref
->name
)) {
7745 /* but update level if needed */
7746 if (level
< dllref
->level
)
7747 dllref
->level
= level
;
7752 // printf("loading dll '%s'\n", soname);
7754 /* add the dll and its level */
7755 dllref
= malloc(sizeof(DLLReference
) + strlen(soname
));
7756 dllref
->level
= level
;
7757 strcpy(dllref
->name
, soname
);
7758 dynarray_add((void ***)&loaded_dlls
, &nb_loaded_dlls
, dllref
);
7760 /* add dynamic symbols in dynsym_section */
7761 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
7762 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
7763 if (sym_bind
== STB_LOCAL
)
7765 name
= dynstr
+ sym
->st_name
;
7766 add_elf_sym(dynsymtab_section
, sym
->st_value
, sym
->st_size
,
7767 sym
->st_info
, sym
->st_shndx
, name
);
7770 /* load all referenced DLLs */
7771 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
7774 name
= dynstr
+ dt
->d_un
.d_val
;
7775 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7776 dllref
= loaded_dlls
[i
];
7777 if (!strcmp(name
, dllref
->name
))
7778 goto already_loaded
;
7780 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0)
7781 error("referenced dll '%s' not found", name
);
7791 /* return -2 if error and CH_EOF if eof */
7792 static void ld_skipspaces(void)
7794 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
7798 static int ld_get_cmd(char *cmd
, int cmd_size
)
7807 if (!((ch
>= 'a' && ch
<= 'z') ||
7808 (ch
>= 'A' && ch
<= 'Z') ||
7809 (ch
>= '0' && ch
<= '9') ||
7810 strchr("/.-_+=$:\\,~?*", ch
)))
7812 if ((q
- cmd
) >= (cmd_size
- 1))
7821 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
7823 static int tcc_load_ldscript(TCCState
*s1
)
7826 char filename
[1024];
7832 ret
= ld_get_cmd(cmd
, sizeof(cmd
));
7837 // printf("cmd='%s'\n", cmd);
7838 if (!strcmp(cmd
, "INPUT") ||
7839 !strcmp(cmd
, "GROUP")) {
7845 ld_get_cmd(filename
, sizeof(filename
));
7846 tcc_add_file(s1
, filename
);
7850 } else if (ch
== ')') {
7853 } else if (ch
== CH_EOF
) {
7854 error("unexpected end of file");
7864 /* print the position in the source file of PC value 'pc' by reading
7865 the stabs debug information */
7866 static void rt_printline(unsigned long wanted_pc
)
7868 Stab_Sym
*sym
, *sym_end
;
7869 char func_name
[128];
7870 unsigned long func_addr
, last_pc
, pc
;
7871 const char *incl_files
[INCLUDE_STACK_SIZE
];
7872 int incl_index
, len
, last_line_num
, i
;
7873 const char *str
, *p
;
7875 func_name
[0] = '\0';
7878 last_pc
= 0xffffffff;
7880 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7881 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
7882 while (sym
< sym_end
) {
7883 switch(sym
->n_type
) {
7884 /* function start or end */
7886 if (sym
->n_strx
== 0) {
7887 func_name
[0] = '\0';
7890 str
= stabstr_section
->data
+ sym
->n_strx
;
7891 p
= strchr(str
, ':');
7893 pstrcpy(func_name
, sizeof(func_name
), str
);
7896 if (len
> sizeof(func_name
) - 1)
7897 len
= sizeof(func_name
) - 1;
7898 memcpy(func_name
, str
, len
);
7899 func_name
[len
] = '\0';
7901 func_addr
= sym
->n_value
;
7904 /* line number info */
7906 pc
= sym
->n_value
+ func_addr
;
7907 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7910 last_line_num
= sym
->n_desc
;
7914 str
= stabstr_section
->data
+ sym
->n_strx
;
7916 if (incl_index
< INCLUDE_STACK_SIZE
) {
7917 incl_files
[incl_index
++] = str
;
7925 if (sym
->n_strx
== 0) {
7926 incl_index
= 0; /* end of translation unit */
7928 str
= stabstr_section
->data
+ sym
->n_strx
;
7929 /* do not add path */
7931 if (len
> 0 && str
[len
- 1] != '/')
7938 /* did not find line number info: */
7939 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
7942 for(i
= 0; i
< incl_index
- 1; i
++)
7943 fprintf(stderr
, "In file included from %s\n",
7945 if (incl_index
> 0) {
7946 fprintf(stderr
, "%s:%d: ",
7947 incl_files
[incl_index
- 1], last_line_num
);
7949 if (func_name
[0] != '\0') {
7950 fprintf(stderr
, "in function '%s()': ", func_name
);
7954 /* emit a run time error at position 'pc' */
7955 void rt_error(unsigned long pc
, const char *fmt
, ...)
7961 vfprintf(stderr
, fmt
, ap
);
7962 fprintf(stderr
, "\n");
7968 /* signal handler for fatal errors */
7969 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7971 struct ucontext
*uc
= puc
;
7975 pc
= uc
->uc_mcontext
.gregs
[14];
7977 #error please put the right sigcontext field
7982 switch(siginf
->si_code
) {
7985 rt_error(pc
, "division by zero");
7988 rt_error(pc
, "floating point exception");
7994 rt_error(pc
, "dereferencing invalid pointer");
7997 rt_error(pc
, "illegal instruction");
8000 rt_error(pc
, "abort() called");
8003 rt_error(pc
, "caught signal %d", signum
);
8010 /* launch the compiled program with the given arguments */
8011 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8014 int (*prog_main
)(int, char **);
8017 tcc_add_runtime(s1
);
8019 relocate_common_syms();
8021 /* compute relocation address : section are relocated in place */
8022 for(i
= 1; i
< nb_sections
; i
++) {
8024 if (s
->sh_flags
& SHF_ALLOC
)
8025 s
->sh_addr
= (unsigned long)s
->data
;
8030 /* relocate each section */
8031 for(i
= 1; i
< nb_sections
; i
++) {
8033 if ((s
->sh_flags
& SHF_ALLOC
) && s
->reloc
)
8034 relocate_section(s
);
8037 prog_main
= (void *)get_elf_sym_val("main");
8041 error("debug mode currently not available for Windows");
8043 struct sigaction sigact
;
8044 /* install TCC signal handlers to print debug info on fatal
8046 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8047 sigact
.sa_sigaction
= sig_error
;
8048 sigemptyset(&sigact
.sa_mask
);
8049 sigaction(SIGFPE
, &sigact
, NULL
);
8050 sigaction(SIGILL
, &sigact
, NULL
);
8051 sigaction(SIGSEGV
, &sigact
, NULL
);
8052 sigaction(SIGBUS
, &sigact
, NULL
);
8053 sigaction(SIGABRT
, &sigact
, NULL
);
8057 #ifdef CONFIG_TCC_BCHECK
8058 if (do_bounds_check
) {
8061 /* add all known static regions */
8062 p
= (int *)bounds_section
->data
;
8063 p_end
= (int *)bounds_section
->data_ptr
;
8065 __bound_new_region((void *)p
[0], p
[1]);
8071 return (*prog_main
)(argc
, argv
);
8074 TCCState
*tcc_new(void)
8079 s
= malloc(sizeof(TCCState
));
8082 s
->output_type
= TCC_OUTPUT_MEMORY
;
8084 /* default include paths */
8085 tcc_add_include_path(s
, "/usr/include");
8086 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8087 tcc_add_include_path(s
, "/usr/local/include");
8089 /* add all tokens */
8090 tok_ident
= TOK_IDENT
;
8095 tok_alloc(p
, r
- p
- 1);
8099 /* standard defines */
8100 tcc_define_symbol(s
, "__STDC__", NULL
);
8101 #if defined(TCC_TARGET_I386)
8102 tcc_define_symbol(s
, "__i386__", NULL
);
8104 /* tiny C specific defines */
8105 tcc_define_symbol(s
, "__TINYC__", NULL
);
8107 /* default library paths */
8108 tcc_add_library_path(s
, "/usr/local/lib");
8109 tcc_add_library_path(s
, "/usr/lib");
8110 tcc_add_library_path(s
, "/lib");
8112 /* no section zero */
8113 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
8115 /* create standard sections */
8116 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8117 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8118 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8120 /* symbols are always generated for linking stage */
8121 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
8122 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
8123 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
8124 put_elf_str(strtab_section
, "");
8125 symtab_section
->link
= strtab_section
;
8126 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
8127 new_section_hash(".hashtab", SHF_PRIVATE
,
8128 ELF_SYM_HASH_SIZE
, symtab_section
);
8130 /* private symbol table for dynamic symbols */
8131 dynsymtab_section
= new_section(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
);
8132 dynsymtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
8133 dynstrtab_section
= new_section(".dynstrtab", SHT_STRTAB
, SHF_PRIVATE
);
8134 put_elf_str(dynstrtab_section
, "");
8135 dynsymtab_section
->link
= dynstrtab_section
;
8136 put_elf_sym(dynsymtab_section
, 0, 0, 0, 0, 0, NULL
);
8137 new_section_hash(".dynhashtab", SHF_PRIVATE
,
8138 ELF_SYM_HASH_SIZE
, dynsymtab_section
);
8142 void tcc_delete(TCCState
*s
)
8147 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
8151 pathname1
= strdup(pathname
);
8154 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
8158 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
8163 BufferedFile
*saved_file
;
8165 /* find source file type with extension */
8166 ext
= strrchr(filename
, '.');
8172 file
= tcc_open(filename
);
8174 if (flags
& AFF_PRINT_ERROR
) {
8175 error("file '%s' not found", filename
);
8182 if (!ext
|| !strcmp(ext
, "c")) {
8183 /* C file assumed */
8187 /* assume executable format: auto guess file type */
8188 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
8189 error("could not read header");
8190 lseek(fd
, 0, SEEK_SET
);
8192 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8193 ehdr
.e_ident
[1] == ELFMAG1
&&
8194 ehdr
.e_ident
[2] == ELFMAG2
&&
8195 ehdr
.e_ident
[3] == ELFMAG3
) {
8196 file
->line_num
= 0; /* do not display line number if error */
8197 if (ehdr
.e_type
== ET_REL
) {
8198 tcc_load_object_file(s
, fd
, 0);
8199 } else if (ehdr
.e_type
== ET_DYN
) {
8200 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
8202 error("unrecognized ELF file");
8204 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8205 file
->line_num
= 0; /* do not display line number if error */
8206 tcc_load_archive(s
, fd
);
8208 /* as GNU ld, consider it is an ld script if not recognized */
8209 if (tcc_load_ldscript(s
) < 0)
8210 error("unrecognized file type");
8218 void tcc_add_file(TCCState
*s
, const char *filename
)
8220 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8223 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8227 pathname1
= strdup(pathname
);
8230 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
8234 /* find and load a dll. Return non zero if not found */
8235 /* XXX: add '-rpath' option support ? */
8236 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8241 for(i
= 0; i
< nb_library_paths
; i
++) {
8242 snprintf(buf
, sizeof(buf
), "%s/%s",
8243 library_paths
[i
], filename
);
8244 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8250 /* the library name is the same as the argument of the '-l' option */
8251 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8257 /* if we output to memory, then we simply we dlopen(). */
8258 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8259 /* Since the libc is already loaded, we don't need to load it again */
8260 if (!strcmp(libraryname
, "c"))
8262 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8263 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8269 /* first we look for the dynamic library if not static linking */
8271 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8272 if (tcc_add_dll(s
, buf
, 0) == 0)
8276 /* then we look for the static library */
8277 for(i
= 0; i
< nb_library_paths
; i
++) {
8278 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8279 library_paths
[i
], libraryname
);
8280 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8286 int tcc_set_output_type(TCCState
*s
, int output_type
)
8288 s
->output_type
= output_type
;
8290 /* add libc crt1/crti objects */
8291 if (output_type
== TCC_OUTPUT_EXE
||
8292 output_type
== TCC_OUTPUT_DLL
) {
8293 if (output_type
!= TCC_OUTPUT_DLL
)
8294 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8295 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8300 #if !defined(LIBTCC)
8304 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8305 "usage: tcc [-c] [-o outfile] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8306 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
8307 " [--] infile1 [infile2... --] [infile_args...]\n"
8309 "General options:\n"
8310 " -c compile only - generate an object file\n"
8311 " -o outfile set output filename (NOT WORKING YET)\n"
8312 " -bench output compilation statistics\n"
8313 " -- allows multiples input files if no -o option given. Also\n"
8314 " separate input files from runtime arguments\n"
8315 "Preprocessor options:\n"
8316 " -Idir add include path 'dir'\n"
8317 " -Dsym[=val] define 'sym' with value 'val'\n"
8318 " -Usym undefine 'sym'\n"
8319 "C compiler options:\n"
8320 " -g generate runtime debug info\n"
8321 #ifdef CONFIG_TCC_BCHECK
8322 " -b compile with built-in memory and bounds checker (implies -g)\n"
8325 " -Ldir add library path 'dir'\n"
8326 " -llib link with dynamic library 'lib'\n"
8327 " -shared generate a shared library (NOT WORKING YET)\n"
8328 " -static static linking (NOT WORKING YET)\n"
8332 int main(int argc
, char **argv
)
8335 int optind
, output_type
, multiple_files
, i
;
8341 output_type
= TCC_OUTPUT_MEMORY
;
8349 if (optind
>= argc
) {
8359 /* '--' enables multiple files input */
8361 } else if (r
[1] == 'h' || r
[1] == '?') {
8363 } else if (r
[1] == 'I') {
8364 if (tcc_add_include_path(s
, r
+ 2) < 0)
8365 error("too many include paths");
8366 } else if (r
[1] == 'D') {
8369 value
= strchr(sym
, '=');
8374 tcc_define_symbol(s
, sym
, value
);
8375 } else if (r
[1] == 'U') {
8376 tcc_undefine_symbol(s
, r
+ 2);
8377 } else if (r
[1] == 'L') {
8378 tcc_add_library_path(s
, r
+ 2);
8379 } else if (r
[1] == 'l') {
8380 dynarray_add((void ***)&libraries
, &nb_libraries
, r
+ 2);
8381 } else if (!strcmp(r
+ 1, "bench")) {
8383 #ifdef CONFIG_TCC_BCHECK
8384 } else if (r
[1] == 'b') {
8385 if (!do_bounds_check
) {
8386 do_bounds_check
= 1;
8388 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8389 /* create bounds sections */
8390 bounds_section
= new_section(".bounds",
8391 SHT_PROGBITS
, SHF_ALLOC
);
8392 lbounds_section
= new_section(".lbounds",
8393 SHT_PROGBITS
, SHF_ALLOC
);
8394 /* debug is implied */
8398 } else if (r
[1] == 'g') {
8399 #ifdef CONFIG_TCC_BCHECK
8406 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
8407 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8408 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
8409 put_elf_str(stabstr_section
, "");
8410 stab_section
->link
= stabstr_section
;
8411 /* put first entry */
8412 put_stabs("", 0, 0, 0, 0);
8415 /* the following options are only for testing, so not
8419 output_type
= TCC_OUTPUT_OBJ
;
8420 } else if (!strcmp(r
+ 1, "static")) {
8422 } else if (!strcmp(r
+ 1, "shared")) {
8423 output_type
= TCC_OUTPUT_DLL
;
8424 } else if (r
[1] == 'o') {
8428 outfile
= argv
[optind
++];
8430 error("invalid option -- '%s'", r
);
8434 /* if outfile provided without other options, we output an
8436 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8437 output_type
= TCC_OUTPUT_EXE
;
8439 tcc_set_output_type(s
, output_type
);
8441 tcc_add_file(s
, argv
[optind
]);
8442 if (multiple_files
) {
8443 while ((optind
+ 1) < argc
) {
8448 error("'--' expected");
8455 /* add specified libraries */
8456 for(i
= 0; i
< nb_libraries
;i
++) {
8457 if (tcc_add_library(s
, libraries
[i
]) < 0)
8458 error("cannot find -l%s", libraries
[i
]);
8462 printf("total: %d idents, %d lines, %d bytes\n",
8463 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
8466 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8467 tcc_output_file(s
, outfile
);
8470 return tcc_run(s
, argc
- optind
, argv
+ optind
);