2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <sys/ucontext.h>
36 #ifndef CONFIG_TCC_STATIC
43 /* preprocessor debug */
46 /* target selection */
47 //#define TCC_TARGET_I386 /* i386 code generator */
48 //#define TCC_TARGET_IL /* .NET CLI generator */
50 /* default target is I386 */
51 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
52 #define TCC_TARGET_I386
55 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
56 #define CONFIG_TCC_BCHECK /* enable bound checking code */
59 #ifndef CONFIG_TCC_PREFIX
60 #define CONFIG_TCC_PREFIX "/usr/local"
63 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
64 executables or dlls */
65 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
67 /* amount of virtual memory associated to a section (currently, we do
69 #define SECTION_VSIZE (1024 * 1024)
71 #define INCLUDE_STACK_SIZE 32
72 #define IFDEF_STACK_SIZE 64
73 #define VSTACK_SIZE 64
74 #define STRING_MAX_SIZE 1024
76 #define TOK_HASH_SIZE 2048 /* must be a power of two */
77 #define TOK_ALLOC_INCR 512 /* must be a power of two */
78 #define SYM_HASH_SIZE 1031
80 /* token symbol management */
81 typedef struct TokenSym
{
82 struct TokenSym
*hash_next
;
83 int tok
; /* token number */
89 typedef union CValue
{
95 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
97 unsigned long long ull
;
105 typedef struct SValue
{
107 unsigned short r
; /* register + flags */
108 unsigned short r2
; /* second register, used for 'long long'
109 type. If not used, set to VT_CONST */
110 CValue c
; /* constant, if VT_CONST */
113 /* symbol management */
115 int v
; /* symbol token */
116 int t
; /* associated type */
117 int r
; /* associated register */
118 int c
; /* associated number */
119 struct Sym
*next
; /* next related symbol */
120 struct Sym
*prev
; /* prev symbol in stack */
121 struct Sym
*hash_next
; /* next symbol in hash table */
124 typedef struct SymStack
{
126 struct Sym
*hash
[SYM_HASH_SIZE
];
129 /* section definition */
130 /* XXX: use directly ELF structure for parameters ? */
131 /* special flag to indicate that the section should not be linked to
133 #define SHF_PRIVATE 0x80000000
135 typedef struct Section
{
136 unsigned long data_offset
; /* current data offset */
137 unsigned char *data
; /* section data */
138 int sh_name
; /* elf section name (only used during output) */
139 int sh_num
; /* elf section number */
140 int sh_type
; /* elf section type */
141 int sh_flags
; /* elf section flags */
142 int sh_info
; /* elf section info */
143 int sh_addralign
; /* elf section alignment */
144 int sh_entsize
; /* elf entry size */
145 unsigned long sh_size
; /* section size (only used during output) */
146 unsigned long sh_addr
; /* address at which the section is relocated */
147 unsigned long sh_offset
; /* address at which the section is relocated */
148 int nb_hashed_syms
; /* used to resize the hash table */
149 struct Section
*link
; /* link to another section */
150 struct Section
*reloc
; /* corresponding section for relocation, if any */
151 struct Section
*hash
; /* hash table for symbols */
152 struct Section
*next
;
153 char name
[64]; /* section name */
156 typedef struct DLLReference
{
161 /* GNUC attribute definition */
162 typedef struct AttributeDef
{
165 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
168 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
169 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
170 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
172 /* stored in 'Sym.c' field */
173 #define FUNC_NEW 1 /* ansi function prototype */
174 #define FUNC_OLD 2 /* old function prototype */
175 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
177 /* stored in 'Sym.r' field */
178 #define FUNC_CDECL 0 /* standard c call */
179 #define FUNC_STDCALL 1 /* pascal c call */
181 /* field 'Sym.t' for macros */
182 #define MACRO_OBJ 0 /* object like macro */
183 #define MACRO_FUNC 1 /* function like macro */
185 /* field 'Sym.t' for labels */
186 #define LABEL_FORWARD 1 /* label is forward defined */
188 /* type_decl() types */
189 #define TYPE_ABSTRACT 1 /* type without variable */
190 #define TYPE_DIRECT 2 /* type with variable */
192 #define IO_BUF_SIZE 8192
194 typedef struct BufferedFile
{
195 unsigned char *buf_ptr
;
196 unsigned char *buf_end
;
198 int line_num
; /* current line number - here to simply code */
199 char filename
[1024]; /* current filename - here to simplify code */
200 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
203 #define CH_EOB 0 /* end of buffer or '\0' char in file */
204 #define CH_EOF (-1) /* end of file */
206 /* parsing state (used to save parser state to reparse part of the
207 source several times) */
208 typedef struct ParseState
{
215 /* used to record tokens */
216 typedef struct TokenString
{
223 struct BufferedFile
*file
;
224 int ch
, ch1
, tok
, tok1
;
226 int return_linefeed
; /* if true, line feed is returned as a token */
230 int nb_sections
; /* number of sections, including first dummy section */
231 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
232 Section
*cur_text_section
; /* current section where function code is
234 /* bound check related sections */
235 Section
*bounds_section
; /* contains global data bound description */
236 Section
*lbounds_section
; /* contains local data bound description */
237 /* symbol sections */
238 Section
*symtab_section
, *strtab_section
;
239 /* temporary dynamic symbol sections (for dll loading) */
240 Section
*dynsymtab_section
;
241 /* exported dynamic symbol section */
245 unsigned long *got_offsets
;
248 /* give the correspondance from symtab indexes to dynsym indexes */
249 int *symtab_to_dynsym
;
251 /* array of all loaded dlls (including those referenced by loaded
253 DLLReference
**loaded_dlls
;
257 Section
*stab_section
, *stabstr_section
;
259 char **library_paths
;
260 int nb_library_paths
;
262 /* loc : local variable index
263 ind : output code index
265 anon_sym: anonymous symbol index
268 prog
, ind
, loc
, const_wanted
;
269 int global_expr
; /* true if compound literals must be allocated
270 globally (used during initializers parsing */
271 int func_vt
, func_vc
; /* current function return type (used by
272 return instruction) */
273 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
275 TokenSym
**table_ident
;
276 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
277 char token_buf
[STRING_MAX_SIZE
+ 1];
279 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
281 SValue vstack
[VSTACK_SIZE
], *vtop
;
282 int *macro_ptr
, *macro_ptr_allocated
;
283 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
284 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
285 char **include_paths
;
286 int nb_include_paths
;
287 int char_pointer_type
;
290 /* compile with debug symbol (and use them if error during execution) */
293 /* compile with built-in memory and bounds checker */
294 int do_bounds_check
= 0;
296 /* display benchmark infos */
301 /* use GNU C extensions */
304 /* use Tiny C extensions */
307 /* if true, static linking is performed */
310 /* give the path of the tcc libraries */
311 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
317 /* The current value can be: */
318 #define VT_VALMASK 0x00ff
319 #define VT_CONST 0x00f0 /* constant in vc
320 (must be first non register value) */
321 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
322 #define VT_LOCAL 0x00f2 /* offset on stack */
323 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
324 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
325 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
326 #define VT_LVAL 0x0100 /* var is an lvalue */
327 #define VT_SYM 0x0200 /* a symbol value is added */
328 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
329 char/short stored in integer registers) */
330 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
331 dereferencing value */
332 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
333 bounding function call point is in vc */
334 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
335 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
336 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
337 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
340 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
342 #define VT_INT 0 /* integer type */
343 #define VT_BYTE 1 /* signed byte type */
344 #define VT_SHORT 2 /* short type */
345 #define VT_VOID 3 /* void type */
346 #define VT_PTR 4 /* pointer */
347 #define VT_ENUM 5 /* enum definition */
348 #define VT_FUNC 6 /* function type */
349 #define VT_STRUCT 7 /* struct/union definition */
350 #define VT_FLOAT 8 /* IEEE float */
351 #define VT_DOUBLE 9 /* IEEE double */
352 #define VT_LDOUBLE 10 /* IEEE long double */
353 #define VT_BOOL 11 /* ISOC99 boolean type */
354 #define VT_LLONG 12 /* 64 bit integer */
355 #define VT_LONG 13 /* long integer (NEVER USED as type, only
357 #define VT_BTYPE 0x000f /* mask for basic type */
358 #define VT_UNSIGNED 0x0010 /* unsigned type */
359 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
360 #define VT_BITFIELD 0x0040 /* bitfield modifier */
363 #define VT_EXTERN 0x00000080 /* extern definition */
364 #define VT_STATIC 0x00000100 /* static variable */
365 #define VT_TYPEDEF 0x00000200 /* typedef definition */
367 /* type mask (except storage) */
368 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
372 /* warning: the following compare tokens depend on i386 asm code */
384 #define TOK_LAND 0xa0
388 #define TOK_MID 0xa3 /* inc/dec, to void constant */
390 #define TOK_UDIV 0xb0 /* unsigned division */
391 #define TOK_UMOD 0xb1 /* unsigned modulo */
392 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
393 #define TOK_CINT 0xb3 /* number in tokc */
394 #define TOK_CCHAR 0xb4 /* char constant in tokc */
395 #define TOK_STR 0xb5 /* pointer to string in tokc */
396 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
397 #define TOK_LCHAR 0xb7
398 #define TOK_LSTR 0xb8
399 #define TOK_CFLOAT 0xb9 /* float constant */
400 #define TOK_LINENUM 0xba /* line number info */
401 #define TOK_CDOUBLE 0xc0 /* double constant */
402 #define TOK_CLDOUBLE 0xc1 /* long double constant */
403 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
404 #define TOK_ADDC1 0xc3 /* add with carry generation */
405 #define TOK_ADDC2 0xc4 /* add with carry use */
406 #define TOK_SUBC1 0xc5 /* add with carry generation */
407 #define TOK_SUBC2 0xc6 /* add with carry use */
408 #define TOK_CUINT 0xc8 /* unsigned int constant */
409 #define TOK_CLLONG 0xc9 /* long long constant */
410 #define TOK_CULLONG 0xca /* unsigned long long constant */
411 #define TOK_ARROW 0xcb
412 #define TOK_DOTS 0xcc /* three dots */
413 #define TOK_SHR 0xcd /* unsigned shift right */
415 #define TOK_SHL 0x01 /* shift left */
416 #define TOK_SAR 0x02 /* signed shift right */
418 /* assignement operators : normal operator or 0x80 */
419 #define TOK_A_MOD 0xa5
420 #define TOK_A_AND 0xa6
421 #define TOK_A_MUL 0xaa
422 #define TOK_A_ADD 0xab
423 #define TOK_A_SUB 0xad
424 #define TOK_A_DIV 0xaf
425 #define TOK_A_XOR 0xde
426 #define TOK_A_OR 0xfc
427 #define TOK_A_SHL 0x81
428 #define TOK_A_SAR 0x82
430 #define TOK_EOF (-1) /* end of file */
431 #define TOK_LINEFEED 10 /* line feed */
433 /* all identificators and strings have token above that */
434 #define TOK_IDENT 256
455 /* ignored types Must have contiguous values */
461 TOK___SIGNED__
, /* gcc keyword */
464 TOK___INLINE__
, /* gcc keyword */
467 /* unsupported type */
481 /* preprocessor only */
482 TOK_UIDENT
, /* first "user" ident (not keyword) */
483 TOK_DEFINE
= TOK_UIDENT
,
499 /* special identifiers */
502 #define DEF(id, str) id,
508 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
509 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
510 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
511 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
512 "sizeof\0__attribute__\0"
513 /* the following are not keywords. They are included to ease parsing */
514 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
515 "defined\0undef\0error\0line\0"
516 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
518 /* builtin functions */
519 #define DEF(id, str) str "\0"
525 #define snprintf _snprintf
528 #if defined(WIN32) || defined(TCC_UCLIBC)
529 /* currently incorrect */
530 long double strtold(const char *nptr
, char **endptr
)
532 return (long double)strtod(nptr
, endptr
);
534 float strtof(const char *nptr
, char **endptr
)
536 return (float)strtod(nptr
, endptr
);
539 /* XXX: need to define this to use them in non ISOC99 context */
540 extern float strtof (const char *__nptr
, char **__endptr
);
541 extern long double strtold (const char *__nptr
, char **__endptr
);
544 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
545 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
549 void next_nomacro(void);
550 int expr_const(void);
554 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
555 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
558 void gv2(int rc1
, int rc2
);
559 void move_reg(int r
, int s
);
560 void save_regs(int n
);
561 void save_reg(int r
);
567 void macro_subst(TokenString
*tok_str
,
568 Sym
**nested_list
, int *macro_str
);
569 int save_reg_forced(int r
);
571 void force_charshort_cast(int t
);
572 void gen_cast(int t
);
574 Sym
*sym_find(int v
);
575 Sym
*sym_push(int v
, int t
, int r
, int c
);
578 int type_size(int t
, int *a
);
579 int pointed_type(int t
);
580 int pointed_size(int t
);
581 int is_compatible_types(int t1
, int t2
);
582 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
583 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
585 void error(const char *fmt
, ...);
586 void rt_error(unsigned long pc
, const char *fmt
, ...);
588 void vset(int t
, int r
, int v
);
589 void type_to_str(char *buf
, int buf_size
,
590 int t
, const char *varstr
);
591 char *get_tok_str(int v
, CValue
*cv
);
592 Sym
*external_sym(int v
, int u
, int r
);
593 static Sym
*get_sym_ref(int t
, Section
*sec
,
594 unsigned long offset
, unsigned long size
);
596 /* section generation */
597 static void *section_ptr(Section
*sec
, unsigned long size
);
598 static void *section_ptr_add(Section
*sec
, unsigned long size
);
599 static void put_extern_sym(Sym
*sym
, Section
*section
,
600 unsigned long value
, unsigned long size
);
601 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
602 static int put_elf_str(Section
*s
, const char *sym
);
603 static int put_elf_sym(Section
*s
,
604 unsigned long value
, unsigned long size
,
605 int info
, int other
, int shndx
, const char *name
);
606 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
607 int type
, int symbol
);
608 static void put_stabs(const char *str
, int type
, int other
, int desc
,
609 unsigned long value
);
610 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
611 unsigned long value
, Section
*sec
, int sym_index
);
612 static void put_stabn(int type
, int other
, int desc
, int value
);
613 static void put_stabd(int type
, int other
, int desc
);
614 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
616 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
617 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
618 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
620 /* true if float/double/long double type */
621 static inline int is_float(int t
)
625 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
628 #ifdef TCC_TARGET_I386
629 #include "i386-gen.c"
635 #ifdef CONFIG_TCC_STATIC
637 #define RTLD_LAZY 0x001
638 #define RTLD_NOW 0x002
639 #define RTLD_GLOBAL 0x100
641 /* dummy function for profiling */
642 void *dlopen(const char *filename
, int flag
)
647 const char *dlerror(void)
652 typedef struct TCCSyms
{
657 #define TCCSYM(a) { #a, &a, },
659 /* add the symbol you want here if no dynamic linking is done */
660 static TCCSyms tcc_syms
[] = {
668 void *dlsym(void *handle
, const char *symbol
)
672 while (p
->str
!= NULL
) {
673 if (!strcmp(p
->str
, symbol
))
682 /********************************************************/
684 /* we use our own 'finite' function to avoid potential problems with
685 non standard math libs */
686 /* XXX: endianness dependant */
687 int ieee_finite(double d
)
690 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
693 /* copy a string and truncate it. */
694 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
701 q_end
= buf
+ buf_size
- 1;
713 /* strcat and truncate. */
714 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
719 pstrcpy(buf
+ len
, buf_size
- len
, s
);
723 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
730 /* every power of two we double array size */
731 if ((nb
& (nb
- 1)) == 0) {
736 pp
= realloc(pp
, nb_alloc
* sizeof(void *));
738 error("memory full");
745 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
750 sec
= malloc(sizeof(Section
));
752 error("memory full");
753 memset(sec
, 0, sizeof(Section
));
754 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
755 sec
->sh_type
= sh_type
;
756 sec
->sh_flags
= sh_flags
;
763 sec
->sh_addralign
= 4;
766 sec
->sh_addralign
= 1;
769 sec
->sh_addralign
= 32; /* default conservative alignment */
773 /* XXX: currently, a single malloc */
774 data
= malloc(SECTION_VSIZE
);
776 error("could not alloc section '%s'", name
);
778 data
= mmap(NULL
, SECTION_VSIZE
,
779 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
780 MAP_PRIVATE
| MAP_ANONYMOUS
,
782 if (data
== (void *)(-1))
783 error("could not mmap section '%s'", name
);
786 sec
->data_offset
= 0;
788 /* only add section if not private */
789 if (!(sh_flags
& SHF_PRIVATE
)) {
790 sec
->sh_num
= nb_sections
;
791 dynarray_add((void ***)§ions
, &nb_sections
, sec
);
796 /* reserve at least 'size' bytes in section 'sec' from sec->data_offset */
797 static void *section_ptr(Section
*sec
, unsigned long size
)
799 return sec
->data
+ sec
->data_offset
;
802 static void *section_ptr_add(Section
*sec
, unsigned long size
)
805 ptr
= sec
->data
+ sec
->data_offset
;
806 sec
->data_offset
+= size
;
810 /* return a reference to a section, and create it if it does not
812 Section
*find_section(const char *name
)
816 for(i
= 1; i
< nb_sections
; i
++) {
818 if (!strcmp(name
, sec
->name
))
821 /* sections are created as PROGBITS */
822 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
825 /* add a new relocation entry to symbol 'sym' in section 's' */
826 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
829 put_extern_sym(sym
, NULL
, 0, 0);
830 /* now we can add ELF relocation info */
831 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
834 static inline int isid(int c
)
836 return (c
>= 'a' && c
<= 'z') ||
837 (c
>= 'A' && c
<= 'Z') ||
841 static inline int isnum(int c
)
843 return c
>= '0' && c
<= '9';
846 static inline int toup(int c
)
848 if (ch
>= 'a' && ch
<= 'z')
849 return ch
- 'a' + 'A';
859 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
860 fprintf(stderr
, "In file included from %s:%d:\n",
861 (*f
)->filename
, (*f
)->line_num
);
862 if (file
->line_num
> 0) {
863 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
865 fprintf(stderr
, "%s: ", file
->filename
);
868 fprintf(stderr
, "tcc: ");
872 void error(const char *fmt
, ...)
877 vfprintf(stderr
, fmt
, ap
);
878 fprintf(stderr
, "\n");
883 void expect(const char *msg
)
885 error("%s expected", msg
);
888 void warning(const char *fmt
, ...)
894 fprintf(stderr
, "warning: ");
895 vfprintf(stderr
, fmt
, ap
);
896 fprintf(stderr
, "\n");
903 error("'%c' expected", c
);
907 void test_lvalue(void)
909 if (!(vtop
->r
& VT_LVAL
))
913 TokenSym
*tok_alloc(const char *str
, int len
)
915 TokenSym
*ts
, **pts
, **ptable
;
922 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
924 pts
= &hash_ident
[h
];
929 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
931 pts
= &(ts
->hash_next
);
934 if (tok_ident
>= SYM_FIRST_ANOM
)
935 error("memory full");
937 /* expand token table if needed */
938 i
= tok_ident
- TOK_IDENT
;
939 if ((i
% TOK_ALLOC_INCR
) == 0) {
940 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
942 error("memory full");
943 table_ident
= ptable
;
946 ts
= malloc(sizeof(TokenSym
) + len
);
948 error("memory full");
950 ts
->tok
= tok_ident
++;
952 ts
->hash_next
= NULL
;
953 memcpy(ts
->str
, str
, len
+ 1);
958 void add_char(char **pp
, int c
)
962 if (c
== '\'' || c
== '\"' || c
== '\\') {
963 /* XXX: could be more precise if char or string */
966 if (c
>= 32 && c
<= 126) {
973 *p
++ = '0' + ((c
>> 6) & 7);
974 *p
++ = '0' + ((c
>> 3) & 7);
975 *p
++ = '0' + (c
& 7);
981 /* XXX: buffer overflow */
982 char *get_tok_str(int v
, CValue
*cv
)
984 static char buf
[STRING_MAX_SIZE
+ 1];
989 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
990 sprintf(buf
, "%u", cv
->ui
);
992 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
999 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
1003 for(i
=0;i
<ts
->len
;i
++)
1004 add_char(&p
, ts
->str
[i
]);
1008 } else if (v
< TOK_IDENT
) {
1013 } else if (v
< tok_ident
) {
1014 return table_ident
[v
- TOK_IDENT
]->str
;
1015 } else if (v
>= SYM_FIRST_ANOM
) {
1016 /* special name for anonymous symbol */
1017 sprintf(buf
, "L.%u", v
- SYM_FIRST_ANOM
);
1020 /* should never happen */
1025 /* push, without hashing */
1026 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1029 s
= malloc(sizeof(Sym
));
1031 error("memory full");
1042 /* find a symbol and return its associated structure. 's' is the top
1043 of the symbol stack */
1044 Sym
*sym_find2(Sym
*s
, int v
)
1054 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1056 /* find a symbol and return its associated structure. 'st' is the
1058 Sym
*sym_find1(SymStack
*st
, int v
)
1062 s
= st
->hash
[HASH_SYM(v
)];
1071 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1074 s
= sym_push2(&st
->top
, v
, t
, c
);
1075 /* add in hash table */
1077 ps
= &st
->hash
[HASH_SYM(v
)];
1084 /* find a symbol in the right symbol space */
1085 Sym
*sym_find(int v
)
1088 s
= sym_find1(&local_stack
, v
);
1090 s
= sym_find1(&global_stack
, v
);
1094 /* push a given symbol on the symbol stack */
1095 Sym
*sym_push(int v
, int t
, int r
, int c
)
1098 if (local_stack
.top
)
1099 s
= sym_push1(&local_stack
, v
, t
, c
);
1101 s
= sym_push1(&global_stack
, v
, t
, c
);
1106 /* pop symbols until top reaches 'b' */
1107 void sym_pop(SymStack
*st
, Sym
*b
)
1114 /* free hash table entry, except if symbol was freed (only
1115 used for #undef symbols) */
1117 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1124 /* undefined a hashed symbol (used for #undef). Its name is set to
1126 void sym_undef(SymStack
*st
, Sym
*s
)
1129 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1130 while (*ss
!= NULL
) {
1133 ss
= &(*ss
)->hash_next
;
1141 BufferedFile
*tcc_open(const char *filename
)
1146 fd
= open(filename
, O_RDONLY
);
1149 bf
= malloc(sizeof(BufferedFile
));
1155 bf
->buf_ptr
= bf
->buffer
;
1156 bf
->buf_end
= bf
->buffer
;
1157 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1158 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1160 // printf("opening '%s'\n", filename);
1164 void tcc_close(BufferedFile
*bf
)
1166 total_lines
+= bf
->line_num
;
1171 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1172 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1174 /* fill input buffer and return next char */
1175 int tcc_getc_slow(BufferedFile
*bf
)
1178 /* only tries to read if really end of buffer */
1179 if (bf
->buf_ptr
>= bf
->buf_end
) {
1181 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1188 bf
->buf_ptr
= bf
->buffer
;
1189 bf
->buf_end
= bf
->buffer
+ len
;
1190 *bf
->buf_end
= CH_EOB
;
1192 if (bf
->buf_ptr
< bf
->buf_end
) {
1193 return *bf
->buf_ptr
++;
1195 bf
->buf_ptr
= bf
->buf_end
;
1200 /* no need to put that inline */
1201 void handle_eob(void)
1204 ch1
= tcc_getc_slow(file
);
1208 if (include_stack_ptr
== include_stack
)
1210 /* add end of include file debug info */
1212 put_stabd(N_EINCL
, 0, 0);
1214 /* pop include stack */
1216 include_stack_ptr
--;
1217 file
= *include_stack_ptr
;
1221 /* read next char from current input file */
1222 static inline void inp(void)
1224 ch1
= TCC_GETC(file
);
1225 /* end of buffer/file handling */
1230 // printf("ch1=%c 0x%x\n", ch1, ch1);
1233 /* input with '\\n' handling */
1234 static inline void minp(void)
1239 if (ch
== '\\' && ch1
== '\n') {
1243 //printf("ch=%c 0x%x\n", ch, ch);
1247 /* same as minp, but also skip comments */
1255 /* single line C++ comments */
1257 while (ch1
!= '\n' && ch1
!= -1)
1260 ch
= ' '; /* return space */
1261 } else if (ch1
== '*') {
1267 if (c
== '*' && ch1
== '/') {
1269 ch
= ' '; /* return space */
1281 void skip_spaces(void)
1283 while (ch
== ' ' || ch
== '\t')
1287 /* skip block of text until #else, #elif or #endif. skip also pairs of
1289 void preprocess_skip(void)
1294 while (ch
!= '\n') {
1305 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1307 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1309 else if (tok
== TOK_ENDIF
)
1315 /* ParseState handling */
1317 /* XXX: currently, no include file info is stored. Thus, we cannot display
1318 accurate messages if the function or data definition spans multiple
1321 /* save current parse state in 's' */
1322 void save_parse_state(ParseState
*s
)
1324 s
->line_num
= file
->line_num
;
1325 s
->macro_ptr
= macro_ptr
;
1330 /* restore parse state from 's' */
1331 void restore_parse_state(ParseState
*s
)
1333 file
->line_num
= s
->line_num
;
1334 macro_ptr
= s
->macro_ptr
;
1339 /* return the number of additionnal 'ints' necessary to store the
1341 static inline int tok_ext_size(int t
)
1359 return LDOUBLE_SIZE
/ 4;
1365 /* token string handling */
1367 static inline void tok_str_new(TokenString
*s
)
1371 s
->last_line_num
= -1;
1374 static void tok_str_add(TokenString
*s
, int t
)
1380 if ((len
& 63) == 0) {
1381 str
= realloc(str
, (len
+ 64) * sizeof(int));
1390 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1394 n
= tok_ext_size(t
);
1396 tok_str_add(s
, cv
->tab
[i
]);
1399 /* add the current parse token in token string 's' */
1400 static void tok_str_add_tok(TokenString
*s
)
1404 /* save line number info */
1405 if (file
->line_num
!= s
->last_line_num
) {
1406 s
->last_line_num
= file
->line_num
;
1407 cval
.i
= s
->last_line_num
;
1408 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1410 tok_str_add2(s
, tok
, &tokc
);
1413 /* get a token from an integer array and increment pointer accordingly */
1414 static int tok_get(int **tok_str
, CValue
*cv
)
1420 n
= tok_ext_size(t
);
1427 /* eval an expression for #if/#elif */
1428 int expr_preprocess(void)
1434 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1435 next(); /* do macro subst */
1436 if (tok
== TOK_DEFINED
) {
1441 c
= sym_find1(&define_stack
, tok
) != 0;
1446 } else if (tok
>= TOK_IDENT
) {
1447 /* if undefined macro */
1451 tok_str_add_tok(&str
);
1453 tok_str_add(&str
, -1); /* simulate end of file */
1454 tok_str_add(&str
, 0);
1455 /* now evaluate C constant expression */
1456 macro_ptr
= str
.str
;
1464 #if defined(DEBUG) || defined(PP_DEBUG)
1465 void tok_print(int *str
)
1471 t
= tok_get(&str
, &cval
);
1474 printf(" %s", get_tok_str(t
, &cval
));
1480 /* parse after #define */
1481 void parse_define(void)
1483 Sym
*s
, *first
, **ps
;
1484 int v
, t
, varg
, is_vaargs
;
1488 /* XXX: should check if same macro (ANSI) */
1491 /* '(' must be just after macro definition for MACRO_FUNC */
1496 while (tok
!= ')') {
1500 if (varg
== TOK_DOTS
) {
1501 varg
= TOK___VA_ARGS__
;
1503 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1507 if (varg
< TOK_IDENT
)
1508 error("badly punctuated parameter list");
1509 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1521 if (ch
== '\n' || ch
== -1)
1524 tok_str_add2(&str
, tok
, &tokc
);
1526 tok_str_add(&str
, 0);
1528 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1531 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1535 void preprocess(void)
1538 char buf
[1024], *q
, *p
;
1543 return_linefeed
= 1; /* linefeed will be returned as a token */
1547 if (tok
== TOK_DEFINE
) {
1550 } else if (tok
== TOK_UNDEF
) {
1552 s
= sym_find1(&define_stack
, tok
);
1553 /* undefine symbol by putting an invalid name */
1555 sym_undef(&define_stack
, s
);
1556 } else if (tok
== TOK_INCLUDE
) {
1561 } else if (ch
== '\"') {
1566 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1567 if ((q
- buf
) < sizeof(buf
) - 1)
1575 error("#include syntax error");
1576 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1579 /* eat all spaces and comments after include */
1580 /* XXX: slightly incorrect */
1581 while (ch1
!= '\n' && ch1
!= -1)
1584 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1585 error("memory full");
1587 /* first search in current dir if "header.h" */
1589 p
= strrchr(file
->filename
, '/');
1591 size
= p
+ 1 - file
->filename
;
1592 if (size
> sizeof(buf1
) - 1)
1593 size
= sizeof(buf1
) - 1;
1594 memcpy(buf1
, file
->filename
, size
);
1596 pstrcat(buf1
, sizeof(buf1
), buf
);
1601 /* now search in standard include path */
1602 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1603 strcpy(buf1
, include_paths
[i
]);
1610 error("include file '%s' not found", buf
);
1613 /* push current file in stack */
1614 /* XXX: fix current line init */
1615 *include_stack_ptr
++ = file
;
1617 /* add include file debug info */
1619 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1623 } else if (tok
== TOK_IFNDEF
) {
1626 } else if (tok
== TOK_IF
) {
1627 c
= expr_preprocess();
1629 } else if (tok
== TOK_IFDEF
) {
1633 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1635 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1636 error("memory full");
1637 *ifdef_stack_ptr
++ = c
;
1639 } else if (tok
== TOK_ELSE
) {
1640 if (ifdef_stack_ptr
== ifdef_stack
)
1641 error("#else without matching #if");
1642 if (ifdef_stack_ptr
[-1] & 2)
1643 error("#else after #else");
1644 c
= (ifdef_stack_ptr
[-1] ^= 3);
1646 } else if (tok
== TOK_ELIF
) {
1647 if (ifdef_stack_ptr
== ifdef_stack
)
1648 error("#elif without matching #if");
1649 c
= ifdef_stack_ptr
[-1];
1651 error("#elif after #else");
1652 /* last #if/#elif expression was true: we skip */
1655 c
= expr_preprocess();
1656 ifdef_stack_ptr
[-1] = c
;
1663 } else if (tok
== TOK_ENDIF
) {
1664 if (ifdef_stack_ptr
== ifdef_stack
)
1665 error("#endif without matching #if");
1667 } else if (tok
== TOK_LINE
) {
1669 if (tok
!= TOK_CINT
)
1671 file
->line_num
= tokc
.i
;
1677 pstrcpy(file
->filename
, sizeof(file
->filename
),
1678 get_tok_str(tok
, &tokc
));
1680 } else if (tok
== TOK_ERROR
) {
1683 /* ignore other preprocess commands or #! for C scripts */
1684 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
1687 return_linefeed
= 0;
1690 /* read a number in base b */
1691 static int getn(int b
)
1696 if (ch
>= 'a' && ch
<= 'f')
1698 else if (ch
>= 'A' && ch
<= 'F')
1704 if (t
< 0 || t
>= b
)
1712 /* read a character for string or char constant and eval escape codes */
1713 static int getq(void)
1721 /* at most three octal digits */
1725 c
= c
* 8 + ch
- '0';
1728 c
= c
* 8 + ch
- '0';
1733 } else if (ch
== 'x') {
1751 else if (ch
== 'e' && gnu_ext
)
1753 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1756 error("invalid escaped char");
1763 /* we use 64 bit numbers */
1766 /* bn = (bn << shift) | or_val */
1767 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1771 for(i
=0;i
<BN_SIZE
;i
++) {
1773 bn
[i
] = (v
<< shift
) | or_val
;
1774 or_val
= v
>> (32 - shift
);
1778 void bn_zero(unsigned int *bn
)
1781 for(i
=0;i
<BN_SIZE
;i
++) {
1786 void parse_number(void)
1788 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1790 unsigned int bn
[BN_SIZE
];
1800 /* special dot handling */
1801 if (ch
>= '0' && ch
<= '9') {
1802 goto float_frac_parse
;
1803 } else if (ch
== '.') {
1814 } else if (t
== '0') {
1815 if (ch
== 'x' || ch
== 'X') {
1819 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1825 /* parse all digits. cannot check octal numbers at this stage
1826 because of floating point constants */
1828 if (ch
>= 'a' && ch
<= 'f')
1830 else if (ch
>= 'A' && ch
<= 'F')
1838 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1840 error("number too long");
1846 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1847 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1849 /* NOTE: strtox should support that for hexa numbers, but
1850 non ISOC99 libcs do not support it, so we prefer to do
1852 /* hexadecimal or binary floats */
1853 /* XXX: handle overflows */
1865 } else if (t
>= 'a') {
1867 } else if (t
>= 'A') {
1872 bn_lshift(bn
, shift
, t
);
1879 if (t
>= 'a' && t
<= 'f') {
1881 } else if (t
>= 'A' && t
<= 'F') {
1883 } else if (t
>= '0' && t
<= '9') {
1889 error("invalid digit");
1890 bn_lshift(bn
, shift
, t
);
1895 if (ch
!= 'p' && ch
!= 'P')
1896 error("exponent expected");
1902 } else if (ch
== '-') {
1906 if (ch
< '0' || ch
> '9')
1907 error("exponent digits expected");
1908 while (ch
>= '0' && ch
<= '9') {
1909 exp_val
= exp_val
* 10 + ch
- '0';
1912 exp_val
= exp_val
* s
;
1914 /* now we can generate the number */
1915 /* XXX: should patch directly float number */
1916 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1917 d
= ldexp(d
, exp_val
- frac_bits
);
1922 /* float : should handle overflow */
1924 } else if (t
== 'L') {
1927 /* XXX: not large enough */
1928 tokc
.ld
= (long double)d
;
1934 /* decimal floats */
1936 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1941 while (ch
>= '0' && ch
<= '9') {
1942 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1948 if (ch
== 'e' || ch
== 'E') {
1949 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1953 if (ch
== '-' || ch
== '+') {
1954 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1959 if (ch
< '0' || ch
> '9')
1960 error("exponent digits expected");
1961 while (ch
>= '0' && ch
<= '9') {
1962 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1974 tokc
.f
= strtof(token_buf
, NULL
);
1975 } else if (t
== 'L') {
1978 tokc
.ld
= strtold(token_buf
, NULL
);
1981 tokc
.d
= strtod(token_buf
, NULL
);
1985 unsigned long long n
, n1
;
1988 /* integer number */
1991 if (b
== 10 && *q
== '0') {
1998 /* no need for checks except for base 10 / 8 errors */
2001 } else if (t
>= 'a') {
2003 } else if (t
>= 'A') {
2008 error("invalid digit");
2012 /* detect overflow */
2014 error("integer constant overflow");
2017 /* XXX: not exactly ANSI compliant */
2018 if ((n
& 0xffffffff00000000LL
) != 0) {
2023 } else if (n
> 0x7fffffff) {
2033 error("three 'l' in integer constant");
2036 if (tok
== TOK_CINT
)
2038 else if (tok
== TOK_CUINT
)
2042 } else if (t
== 'U') {
2043 if (tok
== TOK_CINT
)
2045 else if (tok
== TOK_CLLONG
)
2052 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2060 /* return next token without macro substitution */
2061 void next_nomacro1(void)
2069 while (ch
== '\n') {
2070 /* during preprocessor parsing, '\n' is a token */
2071 if (return_linefeed
) {
2076 while (ch
== ' ' || ch
== '\t')
2079 /* preprocessor command if # at start of line after
2084 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2102 while (isid(ch
) || isnum(ch
)) {
2103 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2104 error("ident too long");
2109 ts
= tok_alloc(token_buf
, q
- token_buf
);
2111 } else if (isnum(ch
) || ch
== '.') {
2113 } else if (ch
== '\'') {
2118 /* this cast is needed if >= 128 */
2119 if (tok
== TOK_CCHAR
)
2125 } else if (ch
== '\"') {
2130 while (ch
!= '\"') {
2133 error("unterminated string");
2134 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2135 error("string too long");
2139 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2142 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2147 if (*q
== tok
&& q
[1] == ch
) {
2150 /* three chars tests */
2151 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2156 } else if (tok
== TOK_DOTS
) {
2158 error("parse error");
2165 /* single char substitutions */
2168 else if (tok
== '>')
2173 /* return next token without macro substitution. Can read input from
2181 tok
= tok_get(¯o_ptr
, &tokc
);
2182 if (tok
== TOK_LINENUM
) {
2183 file
->line_num
= tokc
.i
;
2192 /* substitute args in macro_str and return allocated string */
2193 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2195 int *st
, last_tok
, t
, notfirst
;
2204 t
= tok_get(¯o_str
, &cval
);
2209 t
= tok_get(¯o_str
, &cval
);
2212 s
= sym_find2(args
, t
);
2214 token_buf
[0] = '\0';
2219 pstrcat(token_buf
, sizeof(token_buf
), " ");
2220 t
= tok_get(&st
, &cval
);
2221 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2225 printf("stringize: %s\n", token_buf
);
2228 ts
= tok_alloc(token_buf
, 0);
2230 tok_str_add2(&str
, TOK_STR
, &cval
);
2232 tok_str_add2(&str
, t
, &cval
);
2234 } else if (t
>= TOK_IDENT
) {
2235 s
= sym_find2(args
, t
);
2238 /* if '##' is present before or after, no arg substitution */
2239 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2240 /* special case for var arg macros : ## eats the
2241 ',' if empty VA_ARGS riable. */
2242 /* XXX: test of the ',' is not 100%
2243 reliable. should fix it to avoid security
2245 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2246 last_tok
== TOK_TWOSHARPS
&&
2247 str
.len
>= 2&& str
.str
[str
.len
- 2] == ',') {
2248 /* suppress ',' '##' */
2252 tok_str_add(&str
, *st
++);
2255 macro_subst(&str
, nested_list
, st
);
2258 tok_str_add(&str
, t
);
2261 tok_str_add2(&str
, t
, &cval
);
2265 tok_str_add(&str
, 0);
2269 /* handle the '##' operator */
2270 int *macro_twosharps(int *macro_str
)
2277 TokenString macro_str1
;
2279 tok_str_new(¯o_str1
);
2285 while (*macro_ptr
== TOK_TWOSHARPS
) {
2287 macro_ptr1
= macro_ptr
;
2290 t
= tok_get(¯o_ptr
, &cval
);
2291 /* XXX: we handle only most common cases:
2292 ident + ident or ident + number */
2293 if (tok
>= TOK_IDENT
&&
2294 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2295 p
= get_tok_str(tok
, &tokc
);
2296 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2297 p
= get_tok_str(t
, &cval
);
2298 pstrcat(token_buf
, sizeof(token_buf
), p
);
2299 ts
= tok_alloc(token_buf
, 0);
2300 tok
= ts
->tok
; /* modify current token */
2302 /* cannot merge tokens: skip '##' */
2303 macro_ptr
= macro_ptr1
;
2308 tok_str_add2(¯o_str1
, tok
, &tokc
);
2310 tok_str_add(¯o_str1
, 0);
2311 return macro_str1
.str
;
2314 /* do macro substitution of macro_str and add result to
2315 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2316 substituted. 'nested_list' is the list of all macros we got inside
2317 to avoid recursing. */
2318 void macro_subst(TokenString
*tok_str
,
2319 Sym
**nested_list
, int *macro_str
)
2321 Sym
*s
, *args
, *sa
, *sa1
;
2322 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2323 int mstr_allocated
, *macro_str1
;
2327 saved_macro_ptr
= macro_ptr
;
2328 macro_ptr
= macro_str
;
2331 /* first scan for '##' operator handling */
2332 macro_str1
= macro_twosharps(macro_str
);
2333 macro_ptr
= macro_str1
;
2340 /* special macros */
2341 if (tok
== TOK___LINE__
) {
2342 cval
.i
= file
->line_num
;
2343 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2344 } else if (tok
== TOK___FILE__
) {
2345 cval
.ts
= tok_alloc(file
->filename
, 0);
2346 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2347 } else if (tok
== TOK___DATE__
) {
2348 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2349 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2350 } else if (tok
== TOK___TIME__
) {
2351 cval
.ts
= tok_alloc("00:00:00", 0);
2352 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2353 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2354 /* if symbol is a macro, prepare substitution */
2355 /* if nested substitution, do nothing */
2356 if (sym_find2(*nested_list
, tok
))
2360 if (s
->t
== MACRO_FUNC
) {
2361 /* NOTE: we do not use next_nomacro to avoid eating the
2362 next token. XXX: find better solution */
2366 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2370 if (t
!= '(') /* no macro subst */
2373 /* argument macro */
2378 /* NOTE: empty args are allowed, except if no args */
2380 /* handle '()' case */
2381 if (!args
&& tok
== ')')
2384 error("macro '%s' used with too many args",
2385 get_tok_str(s
->v
, 0));
2388 /* NOTE: non zero sa->t indicates VA_ARGS */
2389 while ((parlevel
> 0 ||
2391 (tok
!= ',' || sa
->t
))) &&
2395 else if (tok
== ')')
2397 tok_str_add2(&str
, tok
, &tokc
);
2400 tok_str_add(&str
, 0);
2401 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2404 /* special case for gcc var args: add an empty
2405 var arg argument if it is omitted */
2406 if (sa
&& sa
->t
&& gnu_ext
)
2416 error("macro '%s' used with too few args",
2417 get_tok_str(s
->v
, 0));
2420 /* now subst each arg */
2421 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2432 sym_push2(nested_list
, s
->v
, 0, 0);
2433 macro_subst(tok_str
, nested_list
, mstr
);
2434 /* pop nested defined symbol */
2436 *nested_list
= sa1
->prev
;
2442 /* no need to add if reading input stream */
2445 tok_str_add2(tok_str
, tok
, &tokc
);
2447 /* only replace one macro while parsing input stream */
2451 macro_ptr
= saved_macro_ptr
;
2456 /* return next token with macro substitution */
2462 /* special 'ungettok' case for label parsing */
2470 /* if not reading from macro substituted string, then try
2472 /* XXX: optimize non macro case */
2475 macro_subst(&str
, &nested_list
, NULL
);
2477 tok_str_add(&str
, 0);
2478 macro_ptr
= str
.str
;
2479 macro_ptr_allocated
= str
.str
;
2487 /* end of macro string: free it */
2488 free(macro_ptr_allocated
);
2495 printf("token = %s\n", get_tok_str(tok
, &tokc
));
2499 void swap(int *p
, int *q
)
2507 void vsetc(int t
, int r
, CValue
*vc
)
2509 if (vtop
>= vstack
+ VSTACK_SIZE
)
2510 error("memory full");
2511 /* cannot let cpu flags if other instruction are generated */
2512 /* XXX: VT_JMP test too ? */
2513 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2518 vtop
->r2
= VT_CONST
;
2522 /* push integer constant */
2527 vsetc(VT_INT
, VT_CONST
, &cval
);
2530 /* Return a static symbol pointing to a section */
2531 static Sym
*get_sym_ref(int t
, Section
*sec
,
2532 unsigned long offset
, unsigned long size
)
2538 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2539 sym
->r
= VT_CONST
| VT_SYM
;
2540 put_extern_sym(sym
, sec
, offset
, size
);
2544 /* push a reference to a section offset by adding a dummy symbol */
2545 void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
2549 cval
.sym
= get_sym_ref(t
, sec
, offset
, size
);
2550 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2553 /* push a reference to symbol v */
2554 void vpush_sym(int t
, int v
)
2559 sym
= external_sym(v
, t
, 0);
2561 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2564 void vset(int t
, int r
, int v
)
2581 void vpushv(SValue
*v
)
2583 if (vtop
>= vstack
+ VSTACK_SIZE
)
2584 error("memory full");
2594 /* save r to the memory stack, and mark it as being free */
2595 void save_reg(int r
)
2597 int l
, i
, saved
, t
, size
, align
;
2600 /* modify all stack values */
2603 for(p
=vstack
;p
<=vtop
;p
++) {
2604 i
= p
->r
& VT_VALMASK
;
2605 if ((p
->r
& VT_VALMASK
) == r
||
2606 (p
->r2
& VT_VALMASK
) == r
) {
2607 /* must save value on stack if not already done */
2609 /* store register in the stack */
2611 if ((p
->r
& VT_LVAL
) ||
2612 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2614 size
= type_size(t
, &align
);
2615 loc
= (loc
- size
) & -align
;
2617 sv
.r
= VT_LOCAL
| VT_LVAL
;
2620 #ifdef TCC_TARGET_I386
2621 /* x86 specific: need to pop fp register ST0 if saved */
2623 o(0xd9dd); /* fstp %st(1) */
2626 /* special long long case */
2627 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2634 /* mark that stack entry as being saved on the stack */
2646 /* find a free register of class 'rc'. If none, save one register */
2652 /* find a free register */
2653 for(r
=0;r
<NB_REGS
;r
++) {
2654 if (reg_classes
[r
] & rc
) {
2655 for(p
=vstack
;p
<=vtop
;p
++) {
2656 if ((p
->r
& VT_VALMASK
) == r
||
2657 (p
->r2
& VT_VALMASK
) == r
)
2665 /* no register left : free the first one on the stack (VERY
2666 IMPORTANT to start from the bottom to ensure that we don't
2667 spill registers used in gen_opi()) */
2668 for(p
=vstack
;p
<=vtop
;p
++) {
2669 r
= p
->r
& VT_VALMASK
;
2670 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2678 /* save registers up to (vtop - n) stack entry */
2679 void save_regs(int n
)
2684 for(p
= vstack
;p
<= p1
; p
++) {
2685 r
= p
->r
& VT_VALMASK
;
2692 /* move register 's' to 'r', and flush previous value of r to memory
2694 void move_reg(int r
, int s
)
2707 /* get address of vtop (vtop MUST BE an lvalue) */
2710 vtop
->r
&= ~VT_LVAL
;
2711 /* tricky: if saved lvalue, then we can go back to lvalue */
2712 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2713 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2716 #ifdef CONFIG_TCC_BCHECK
2717 /* generate lvalue bound code */
2722 vtop
->r
&= ~VT_MUSTBOUND
;
2723 /* if lvalue, then use checking code before dereferencing */
2724 if (vtop
->r
& VT_LVAL
) {
2725 /* if not VT_BOUNDED value, then make one */
2726 if (!(vtop
->r
& VT_BOUNDED
)) {
2727 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2730 gen_bounded_ptr_add();
2731 vtop
->r
|= lval_type
;
2733 /* then check for dereferencing */
2734 gen_bounded_ptr_deref();
2739 /* store vtop a register belonging to class 'rc'. lvalues are
2740 converted to values. Cannot be used if cannot be converted to
2741 register value (such as structures). */
2744 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
2745 unsigned long long ll
;
2747 /* NOTE: get_reg can modify vstack[] */
2748 if (vtop
->t
& VT_BITFIELD
) {
2749 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2750 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2751 /* remove bit field info to avoid loops */
2752 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2753 /* generate shifts */
2754 vpushi(32 - (bit_pos
+ bit_size
));
2756 vpushi(32 - bit_size
);
2757 /* NOTE: transformed to SHR if unsigned */
2761 if (is_float(vtop
->t
) &&
2762 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2765 unsigned long offset
;
2767 /* XXX: unify with initializers handling ? */
2768 /* CPUs usually cannot use float constants, so we store them
2769 generically in data segment */
2770 size
= type_size(vtop
->t
, &align
);
2771 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
2772 data_section
->data_offset
= offset
;
2773 /* XXX: not portable yet */
2774 ptr
= section_ptr_add(data_section
, size
);
2777 ptr
[i
] = vtop
->c
.tab
[i
];
2778 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
2779 vtop
->r
|= VT_LVAL
| VT_SYM
;
2782 #ifdef CONFIG_TCC_BCHECK
2783 if (vtop
->r
& VT_MUSTBOUND
)
2787 r
= vtop
->r
& VT_VALMASK
;
2788 /* need to reload if:
2790 - lvalue (need to dereference pointer)
2791 - already a register, but not in the right class */
2792 if (r
>= VT_CONST
||
2793 (vtop
->r
& VT_LVAL
) ||
2794 !(reg_classes
[r
] & rc
) ||
2795 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2796 !(reg_classes
[vtop
->r2
] & rc
))) {
2798 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2799 /* two register type load : expand to two words
2801 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2804 vtop
->c
.ui
= ll
; /* first word */
2806 vtop
->r
= r
; /* save register value */
2807 vpushi(ll
>> 32); /* second word */
2808 } else if (r
>= VT_CONST
||
2809 (vtop
->r
& VT_LVAL
)) {
2810 /* load from memory */
2813 vtop
[-1].r
= r
; /* save register value */
2814 /* increment pointer to get second word */
2821 /* move registers */
2824 vtop
[-1].r
= r
; /* save register value */
2825 vtop
->r
= vtop
[-1].r2
;
2827 /* allocate second register */
2834 /* write second register */
2836 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2838 /* lvalue of scalar type : need to use lvalue type
2839 because of possible cast */
2842 /* compute memory access type */
2843 if (vtop
->r
& VT_LVAL_BYTE
)
2845 else if (vtop
->r
& VT_LVAL_SHORT
)
2847 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2851 /* restore wanted type */
2854 /* one register type load */
2863 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2864 void gv2(int rc1
, int rc2
)
2866 /* generate more generic register first */
2872 /* test if reload is needed for first register */
2873 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2883 /* test if reload is needed for first register */
2884 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2890 /* expand long long on stack in two int registers */
2895 u
= vtop
->t
& VT_UNSIGNED
;
2898 vtop
[0].r
= vtop
[-1].r2
;
2899 vtop
[0].r2
= VT_CONST
;
2900 vtop
[-1].r2
= VT_CONST
;
2901 vtop
[0].t
= VT_INT
| u
;
2902 vtop
[-1].t
= VT_INT
| u
;
2905 /* build a long long from two ints */
2908 gv2(RC_INT
, RC_INT
);
2909 vtop
[-1].r2
= vtop
[0].r
;
2914 /* rotate n first stack elements to the bottom */
2921 for(i
=-n
+1;i
!=0;i
++)
2922 vtop
[i
] = vtop
[i
+1];
2926 /* pop stack value */
2930 v
= vtop
->r
& VT_VALMASK
;
2931 #ifdef TCC_TARGET_I386
2932 /* for x86, we need to pop the FP stack */
2934 o(0xd9dd); /* fstp %st(1) */
2937 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2938 /* need to put correct jump if && or || without test */
2944 /* convert stack entry to register and duplicate its value in another
2952 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2959 /* stack: H L L1 H1 */
2967 /* duplicate value */
2978 load(r1
, &sv
); /* move r to r1 */
2980 /* duplicates value */
2985 /* generate CPU independent (unsigned) long long operations */
2986 void gen_opl(int op
)
2988 int t
, a
, b
, op1
, c
, i
;
2996 func
= TOK___divdi3
;
2999 func
= TOK___udivdi3
;
3002 func
= TOK___moddi3
;
3005 func
= TOK___umoddi3
;
3007 /* call generic long long function */
3008 gfunc_start(&gf
, FUNC_CDECL
);
3011 vpush_sym(func_old_type
, func
);
3015 vtop
->r2
= REG_LRET
;
3028 /* stack: L1 H1 L2 H2 */
3033 vtop
[-2] = vtop
[-3];
3036 /* stack: H1 H2 L1 L2 */
3042 /* stack: H1 H2 L1 L2 ML MH */
3045 /* stack: ML MH H1 H2 L1 L2 */
3049 /* stack: ML MH H1 L2 H2 L1 */
3054 /* stack: ML MH M1 M2 */
3057 } else if (op
== '+' || op
== '-') {
3058 /* XXX: add non carry method too (for MIPS or alpha) */
3064 /* stack: H1 H2 (L1 op L2) */
3067 gen_op(op1
+ 1); /* TOK_xxxC2 */
3070 /* stack: H1 H2 (L1 op L2) */
3073 /* stack: (L1 op L2) H1 H2 */
3075 /* stack: (L1 op L2) (H1 op H2) */
3083 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3088 /* stack: L H shift */
3090 /* constant: simpler */
3091 /* NOTE: all comments are for SHL. the other cases are
3092 done by swaping words */
3103 if (op
!= TOK_SAR
) {
3133 /* XXX: should provide a faster fallback on x86 ? */
3136 func
= TOK___sardi3
;
3139 func
= TOK___shrdi3
;
3142 func
= TOK___shldi3
;
3148 /* compare operations */
3154 /* stack: L1 H1 L2 H2 */
3156 vtop
[-1] = vtop
[-2];
3158 /* stack: L1 L2 H1 H2 */
3161 /* when values are equal, we need to compare low words. since
3162 the jump is inverted, we invert the test too. */
3165 else if (op1
== TOK_GT
)
3167 else if (op1
== TOK_ULT
)
3169 else if (op1
== TOK_UGT
)
3174 if (op1
!= TOK_NE
) {
3178 /* generate non equal test */
3179 /* XXX: NOT PORTABLE yet */
3183 #ifdef TCC_TARGET_I386
3184 b
= psym(0x850f, 0);
3186 error("not implemented");
3194 vset(VT_INT
, VT_JMPI
, a
);
3199 /* handle integer constant optimizations and various machine
3201 void gen_opic(int op
)
3208 /* currently, we cannot do computations with forward symbols */
3209 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3210 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3214 case '+': v1
->c
.i
+= fc
; break;
3215 case '-': v1
->c
.i
-= fc
; break;
3216 case '&': v1
->c
.i
&= fc
; break;
3217 case '^': v1
->c
.i
^= fc
; break;
3218 case '|': v1
->c
.i
|= fc
; break;
3219 case '*': v1
->c
.i
*= fc
; break;
3226 /* if division by zero, generate explicit division */
3229 error("division by zero in constant");
3233 default: v1
->c
.i
/= fc
; break;
3234 case '%': v1
->c
.i
%= fc
; break;
3235 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3236 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3239 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3240 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3241 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3243 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3244 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3245 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3246 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3247 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3248 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3249 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3250 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3251 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3252 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3254 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3255 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3261 /* if commutative ops, put c2 as constant */
3262 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3263 op
== '|' || op
== '*')) {
3268 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3271 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3272 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3278 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3279 /* try to use shifts instead of muls or divs */
3280 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3289 else if (op
== TOK_PDIV
)
3297 /* call low level op generator */
3303 /* generate a floating point operation with constant propagation */
3304 void gen_opif(int op
)
3312 /* currently, we cannot do computations with forward symbols */
3313 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3314 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3316 if (v1
->t
== VT_FLOAT
) {
3319 } else if (v1
->t
== VT_DOUBLE
) {
3327 /* NOTE: we only do constant propagation if finite number (not
3328 NaN or infinity) (ANSI spec) */
3329 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3333 case '+': f1
+= f2
; break;
3334 case '-': f1
-= f2
; break;
3335 case '*': f1
*= f2
; break;
3339 error("division by zero in constant");
3344 /* XXX: also handles tests ? */
3348 /* XXX: overflow test ? */
3349 if (v1
->t
== VT_FLOAT
) {
3351 } else if (v1
->t
== VT_DOUBLE
) {
3364 int pointed_size(int t
)
3366 return type_size(pointed_type(t
), &t
);
3370 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3372 char buf1
[256], buf2
[256];
3376 if (!is_compatible_types(t1
, t2
)) {
3377 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3378 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3379 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3384 /* generic gen_op: handles types problems */
3387 int u
, t1
, t2
, bt1
, bt2
, t
;
3391 bt1
= t1
& VT_BTYPE
;
3392 bt2
= t2
& VT_BTYPE
;
3394 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3395 /* at least one operand is a pointer */
3396 /* relationnal op: must be both pointers */
3397 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3398 // check_pointer_types(vtop, vtop - 1);
3399 /* pointers are handled are unsigned */
3400 t
= VT_INT
| VT_UNSIGNED
;
3403 /* if both pointers, then it must be the '-' op */
3404 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3405 (t2
& VT_BTYPE
) == VT_PTR
) {
3407 error("cannot use pointers here");
3408 // check_pointer_types(vtop - 1, vtop);
3409 /* XXX: check that types are compatible */
3410 u
= pointed_size(t1
);
3412 /* set to integer type */
3417 /* exactly one pointer : must be '+' or '-'. */
3418 if (op
!= '-' && op
!= '+')
3419 error("cannot use pointers here");
3420 /* Put pointer as first operand */
3421 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3425 /* XXX: cast to int ? (long long case) */
3426 vpushi(pointed_size(vtop
[-1].t
));
3428 #ifdef CONFIG_TCC_BCHECK
3429 /* if evaluating constant expression, no code should be
3430 generated, so no bound check */
3431 if (do_bounds_check
&& !const_wanted
) {
3432 /* if bounded pointers, we generate a special code to
3439 gen_bounded_ptr_add();
3445 /* put again type if gen_opic() swaped operands */
3448 } else if (is_float(bt1
) || is_float(bt2
)) {
3449 /* compute bigger type and do implicit casts */
3450 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3452 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3457 /* floats can only be used for a few operations */
3458 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3459 (op
< TOK_ULT
|| op
> TOK_GT
))
3460 error("invalid operands for binary operation");
3462 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3463 /* cast to biggest op */
3465 /* convert to unsigned if it does not fit in a long long */
3466 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3467 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3471 /* integer operations */
3473 /* convert to unsigned if it does not fit in an integer */
3474 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3475 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3478 /* XXX: currently, some unsigned operations are explicit, so
3479 we modify them here */
3480 if (t
& VT_UNSIGNED
) {
3487 else if (op
== TOK_LT
)
3489 else if (op
== TOK_GT
)
3491 else if (op
== TOK_LE
)
3493 else if (op
== TOK_GE
)
3499 /* special case for shifts and long long: we keep the shift as
3501 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3507 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3511 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3512 /* relationnal op: the result is an int */
3520 /* generic itof for unsigned long long case */
3521 void gen_cvt_itof1(int t
)
3525 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3526 (VT_LLONG
| VT_UNSIGNED
)) {
3528 gfunc_start(&gf
, FUNC_CDECL
);
3531 vpush_sym(func_old_type
, TOK___ulltof
);
3532 else if (t
== VT_DOUBLE
)
3533 vpush_sym(func_old_type
, TOK___ulltod
);
3535 vpush_sym(func_old_type
, TOK___ulltold
);
3544 /* generic ftoi for unsigned long long case */
3545 void gen_cvt_ftoi1(int t
)
3550 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3551 /* not handled natively */
3552 gfunc_start(&gf
, FUNC_CDECL
);
3553 st
= vtop
->t
& VT_BTYPE
;
3556 vpush_sym(func_old_type
, TOK___fixunssfdi
);
3557 else if (st
== VT_DOUBLE
)
3558 vpush_sym(func_old_type
, TOK___fixunsdfdi
);
3560 vpush_sym(func_old_type
, TOK___fixunsxfdi
);
3564 vtop
->r2
= REG_LRET
;
3570 /* force char or short cast */
3571 void force_charshort_cast(int t
)
3575 /* XXX: add optimization if lvalue : just change type and offset */
3580 if (t
& VT_UNSIGNED
) {
3581 vpushi((1 << bits
) - 1);
3592 /* cast 'vtop' to 't' type */
3593 void gen_cast(int t
)
3595 int sbt
, dbt
, sf
, df
, c
;
3597 /* special delayed cast for char/short */
3598 /* XXX: in some cases (multiple cascaded casts), it may still
3600 if (vtop
->r
& VT_MUSTCAST
) {
3601 vtop
->r
&= ~VT_MUSTCAST
;
3602 force_charshort_cast(vtop
->t
);
3605 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3606 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3611 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3613 /* convert from fp to fp */
3615 /* constant case: we can do it now */
3616 /* XXX: in ISOC, cannot do it if error in convert */
3617 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3618 vtop
->c
.f
= (float)vtop
->c
.d
;
3619 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3620 vtop
->c
.f
= (float)vtop
->c
.ld
;
3621 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3622 vtop
->c
.d
= (double)vtop
->c
.f
;
3623 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3624 vtop
->c
.d
= (double)vtop
->c
.ld
;
3625 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3626 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3627 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3628 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3630 /* non constant case: generate code */
3634 /* convert int to fp */
3637 case VT_LLONG
| VT_UNSIGNED
:
3639 /* XXX: add const cases for long long */
3641 case VT_INT
| VT_UNSIGNED
:
3643 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3644 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3645 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3650 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3651 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3652 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3661 /* convert fp to int */
3662 /* we handle char/short/etc... with generic code */
3663 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3664 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3669 case VT_LLONG
| VT_UNSIGNED
:
3671 /* XXX: add const cases for long long */
3673 case VT_INT
| VT_UNSIGNED
:
3675 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3676 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3677 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3683 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3684 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3685 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3693 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3694 /* additionnal cast for char/short/bool... */
3698 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3699 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3700 /* scalar to long long */
3702 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3703 vtop
->c
.ll
= vtop
->c
.ui
;
3705 vtop
->c
.ll
= vtop
->c
.i
;
3707 /* machine independant conversion */
3709 /* generate high word */
3710 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3718 /* patch second register */
3719 vtop
[-1].r2
= vtop
->r
;
3723 } else if (dbt
== VT_BOOL
) {
3724 /* scalar to bool */
3727 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3728 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3729 force_charshort_cast(t
);
3730 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3732 if (sbt
== VT_LLONG
) {
3733 /* from long long: just take low order word */
3737 /* if lvalue and single word type, nothing to do because
3738 the lvalue already contains the real type size (see
3739 VT_LVAL_xxx constants) */
3745 /* return type size. Put alignment at 'a' */
3746 int type_size(int t
, int *a
)
3752 if (bt
== VT_STRUCT
) {
3754 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3755 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3757 } else if (bt
== VT_PTR
) {
3759 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3760 return type_size(s
->t
, a
) * s
->c
;
3765 } else if (bt
== VT_LDOUBLE
) {
3767 return LDOUBLE_SIZE
;
3768 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3771 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3774 } else if (bt
== VT_SHORT
) {
3778 /* char, void, function, _Bool */
3784 /* return the pointed type of t */
3785 int pointed_type(int t
)
3788 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3789 return s
->t
| (t
& ~VT_TYPE
);
3792 int mk_pointer(int t
)
3796 sym_push(p
, t
, 0, -1);
3797 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3800 int is_compatible_types(int t1
, int t2
)
3807 bt1
= t1
& VT_BTYPE
;
3808 bt2
= t2
& VT_BTYPE
;
3809 if (bt1
== VT_PTR
) {
3810 t1
= pointed_type(t1
);
3811 /* if function, then convert implicitely to function pointer */
3812 if (bt2
!= VT_FUNC
) {
3815 t2
= pointed_type(t2
);
3817 /* void matches everything */
3820 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3822 return is_compatible_types(t1
, t2
);
3823 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3825 } else if (bt1
== VT_FUNC
) {
3828 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3829 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3830 if (!is_compatible_types(s1
->t
, s2
->t
))
3832 /* XXX: not complete */
3833 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3837 while (s1
!= NULL
) {
3840 if (!is_compatible_types(s1
->t
, s2
->t
))
3849 /* XXX: not complete */
3854 /* print a type. If 'varstr' is not NULL, then the variable is also
3855 printed in the type */
3857 /* XXX: add array and function pointers */
3858 void type_to_str(char *buf
, int buf_size
,
3859 int t
, const char *varstr
)
3869 if (t
& VT_UNSIGNED
)
3870 pstrcat(buf
, buf_size
, "unsigned ");
3900 tstr
= "long double";
3902 pstrcat(buf
, buf_size
, tstr
);
3906 if (bt
== VT_STRUCT
)
3910 pstrcat(buf
, buf_size
, tstr
);
3911 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3912 if (v
>= SYM_FIRST_ANOM
)
3913 pstrcat(buf
, buf_size
, "<anonymous>");
3915 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3918 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3919 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3920 pstrcat(buf
, buf_size
, "(");
3922 while (sa
!= NULL
) {
3923 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3924 pstrcat(buf
, buf_size
, buf1
);
3927 pstrcat(buf
, buf_size
, ", ");
3929 pstrcat(buf
, buf_size
, ")");
3932 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3933 pstrcpy(buf1
, sizeof(buf1
), "*");
3935 pstrcat(buf1
, sizeof(buf1
), varstr
);
3936 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3940 pstrcat(buf
, buf_size
, " ");
3941 pstrcat(buf
, buf_size
, varstr
);
3946 /* verify type compatibility to store vtop in 'dt' type, and generate
3948 void gen_assign_cast(int dt
)
3951 char buf1
[256], buf2
[256];
3953 st
= vtop
->t
; /* source type */
3954 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3955 /* special cases for pointers */
3956 /* a function is implicitely a function pointer */
3957 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3958 if (!is_compatible_types(pointed_type(dt
), st
))
3963 /* '0' can also be a pointer */
3964 if ((st
& VT_BTYPE
) == VT_INT
&&
3965 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3969 if (!is_compatible_types(dt
, st
)) {
3971 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3972 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3973 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3979 /* store vtop in lvalue pushed on stack */
3982 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3986 sbt
= vtop
->t
& VT_BTYPE
;
3987 dbt
= ft
& VT_BTYPE
;
3988 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3989 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3990 /* optimize char/short casts */
3991 delayed_cast
= VT_MUSTCAST
;
3992 vtop
->t
= ft
& VT_TYPE
;
3995 gen_assign_cast(ft
& VT_TYPE
);
3998 if (sbt
== VT_STRUCT
) {
3999 /* if structure, only generate pointer */
4000 /* structure assignment : generate memcpy */
4001 /* XXX: optimize if small size */
4003 gfunc_start(&gf
, FUNC_CDECL
);
4005 size
= type_size(vtop
->t
, &align
);
4019 vpush_sym(func_old_type
, TOK_memcpy
);
4021 /* leave source on stack */
4022 } else if (ft
& VT_BITFIELD
) {
4023 /* bitfield store handling */
4024 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4025 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4026 /* remove bit field info to avoid loops */
4027 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4029 /* duplicate destination */
4031 vtop
[-1] = vtop
[-2];
4033 /* mask and shift source */
4034 vpushi((1 << bit_size
) - 1);
4038 /* load destination, mask and or with source */
4040 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4046 #ifdef CONFIG_TCC_BCHECK
4047 /* bound check case */
4048 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4057 r
= gv(rc
); /* generate value */
4058 /* if lvalue was saved on stack, must read it */
4059 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4061 t
= get_reg(RC_INT
);
4063 sv
.r
= VT_LOCAL
| VT_LVAL
;
4064 sv
.c
.ul
= vtop
[-1].c
.ul
;
4066 vtop
[-1].r
= t
| VT_LVAL
;
4069 /* two word case handling : store second register at word + 4 */
4070 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4072 /* convert to int to increment easily */
4079 /* XXX: it works because r2 is spilled last ! */
4080 store(vtop
->r2
, vtop
- 1);
4083 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4084 vtop
->r
|= delayed_cast
;
4088 /* post defines POST/PRE add. c is the token ++ or -- */
4089 void inc(int post
, int c
)
4092 vdup(); /* save lvalue */
4094 gv_dup(); /* duplicate value */
4099 vpushi(c
- TOK_MID
);
4101 vstore(); /* store value */
4103 vpop(); /* if post op, return saved value */
4106 /* Parse GNUC __attribute__ extension. Currently, the following
4107 extensions are recognized:
4108 - aligned(n) : set data/function alignment.
4109 - section(x) : generate data/code in this section.
4110 - unused : currently ignored, but may be used someday.
4112 void parse_attribute(AttributeDef
*ad
)
4119 while (tok
!= ')') {
4120 if (tok
< TOK_IDENT
)
4121 expect("attribute name");
4126 case TOK___SECTION__
:
4129 expect("section name");
4130 ad
->section
= find_section(tokc
.ts
->str
);
4135 case TOK___ALIGNED__
:
4138 if (n
<= 0 || (n
& (n
- 1)) != 0)
4139 error("alignment must be a positive power of two");
4144 case TOK___UNUSED__
:
4145 /* currently, no need to handle it because tcc does not
4146 track unused objects */
4149 case TOK___NORETURN__
:
4150 /* currently, no need to handle it because tcc does not
4151 track unused objects */
4156 ad
->func_call
= FUNC_CDECL
;
4160 case TOK___STDCALL__
:
4161 ad
->func_call
= FUNC_STDCALL
;
4164 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4165 /* skip parameters */
4166 /* XXX: skip parenthesis too */
4169 while (tok
!= ')' && tok
!= -1)
4183 /* enum/struct/union declaration */
4184 int struct_decl(int u
)
4186 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4187 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4191 a
= tok
; /* save decl type */
4196 /* struct already defined ? return it */
4197 /* XXX: check consistency */
4198 s
= sym_find(v
| SYM_STRUCT
);
4201 error("invalid type");
4207 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4208 /* put struct/union/enum name in type */
4210 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4215 error("struct/union/enum already defined");
4216 /* cannot be empty */
4223 if (a
== TOK_ENUM
) {
4230 /* enum symbols have static storage */
4231 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4236 parse_btype(&b
, &ad
);
4241 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4242 if ((t
& VT_BTYPE
) == VT_FUNC
||
4243 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4244 error("invalid type for '%s'",
4245 get_tok_str(v
, NULL
));
4251 bit_size
= expr_const();
4252 /* XXX: handle v = 0 case for messages */
4254 error("negative width in bit-field '%s'",
4255 get_tok_str(v
, NULL
));
4256 if (v
&& bit_size
== 0)
4257 error("zero width for bit-field '%s'",
4258 get_tok_str(v
, NULL
));
4260 size
= type_size(t
, &align
);
4262 if (bit_size
>= 0) {
4267 error("bitfields must have scalar type");
4269 if (bit_size
> bsize
) {
4270 error("width of '%s' exceeds its type",
4271 get_tok_str(v
, NULL
));
4272 } else if (bit_size
== bsize
) {
4273 /* no need for bit fields */
4275 } else if (bit_size
== 0) {
4276 /* XXX: what to do if only padding in a
4278 /* zero size: means to pad */
4282 /* we do not have enough room ? */
4283 if ((bit_pos
+ bit_size
) > bsize
)
4286 /* XXX: handle LSB first */
4288 (bit_pos
<< VT_STRUCT_SHIFT
) |
4289 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4290 bit_pos
+= bit_size
;
4296 /* add new memory data only if starting
4298 if (lbit_pos
== 0) {
4299 if (a
== TOK_STRUCT
) {
4300 c
= (c
+ align
- 1) & -align
;
4308 if (align
> maxalign
)
4312 printf("add field %s offset=%d",
4313 get_tok_str(v
, NULL
), offset
);
4314 if (t
& VT_BITFIELD
) {
4315 printf(" pos=%d size=%d",
4316 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4317 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4321 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4325 if (tok
== ';' || tok
== -1)
4335 /* size for struct/union, dummy for enum */
4336 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4341 /* return 0 if no type declaration. otherwise, return the basic type
4344 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4346 int t
, u
, type_found
;
4349 memset(ad
, 0, sizeof(AttributeDef
));
4360 if ((t
& VT_BTYPE
) != 0)
4361 error("too many basic types");
4375 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4376 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4377 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4378 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4392 if ((t
& VT_BTYPE
) == VT_LONG
) {
4393 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4400 u
= struct_decl(VT_ENUM
);
4404 u
= struct_decl(VT_STRUCT
);
4407 /* type modifiers */
4412 case TOK___SIGNED__
:
4415 case TOK___INLINE__
:
4437 /* GNUC attribute */
4438 case TOK___ATTRIBUTE__
:
4439 parse_attribute(ad
);
4443 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4445 t
|= (s
->t
& ~VT_TYPEDEF
);
4452 /* long is never used as type */
4453 if ((t
& VT_BTYPE
) == VT_LONG
)
4454 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4459 int post_type(int t
, AttributeDef
*ad
)
4461 int p
, n
, pt
, l
, t1
;
4462 Sym
**plast
, *s
, *first
;
4466 /* function declaration */
4471 while (tok
!= ')') {
4472 /* read param name and compute offset */
4473 if (l
!= FUNC_OLD
) {
4474 if (!parse_btype(&pt
, &ad1
)) {
4476 error("invalid type");
4483 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4485 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4486 if ((pt
& VT_BTYPE
) == VT_VOID
)
4487 error("parameter declared as void");
4494 /* array must be transformed to pointer according to ANSI C */
4496 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4501 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4508 /* if no parameters, then old type prototype */
4512 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4513 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4514 /* we push a anonymous symbol which will contain the function prototype */
4516 s
= sym_push(p
, t
, ad
->func_call
, l
);
4518 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4519 } else if (tok
== '[') {
4520 /* array definition */
4526 error("invalid array size");
4529 /* parse next post type */
4530 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4531 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4533 /* we push a anonymous symbol which will contain the array
4536 sym_push(p
, t
, 0, n
);
4537 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4542 /* Read a type declaration (except basic type), and return the
4543 type. 'td' is a bitmask indicating which kind of type decl is
4544 expected. 't' should contain the basic type. 'ad' is the attribute
4545 definition of the basic type. It can be modified by type_decl(). */
4546 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4551 while (tok
== '*') {
4553 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4558 /* recursive type */
4559 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4562 /* XXX: this is not correct to modify 'ad' at this point, but
4563 the syntax is not clear */
4564 if (tok
== TOK___ATTRIBUTE__
)
4565 parse_attribute(ad
);
4566 u
= type_decl(ad
, v
, 0, td
);
4570 /* type identifier */
4571 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4575 if (!(td
& TYPE_ABSTRACT
))
4576 expect("identifier");
4580 /* append t at the end of u */
4581 t
= post_type(t
, ad
);
4582 if (tok
== TOK___ATTRIBUTE__
)
4583 parse_attribute(ad
);
4588 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4598 /* define a new external reference to a symbol 'v' of type 'u' */
4599 Sym
*external_sym(int v
, int u
, int r
)
4605 /* push forward reference */
4606 s
= sym_push1(&global_stack
,
4607 v
, u
| VT_EXTERN
, 0);
4608 s
->r
= r
| VT_CONST
| VT_SYM
;
4613 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4614 static int lvalue_type(int t
)
4621 else if (bt
== VT_SHORT
)
4625 if (t
& VT_UNSIGNED
)
4626 r
|= VT_LVAL_UNSIGNED
;
4630 /* indirection with full error checking and bound check */
4631 static void indir(void)
4633 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4635 if (vtop
->r
& VT_LVAL
)
4637 vtop
->t
= pointed_type(vtop
->t
);
4638 /* an array is never an lvalue */
4639 if (!(vtop
->t
& VT_ARRAY
)) {
4640 vtop
->r
|= lvalue_type(vtop
->t
);
4641 /* if bound checking, the referenced pointer must be checked */
4642 if (do_bounds_check
)
4643 vtop
->r
|= VT_MUSTBOUND
;
4647 /* pass a parameter to a function and do type checking and casting */
4648 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4651 func_type
= func
->c
;
4652 if (func_type
== FUNC_OLD
||
4653 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4654 /* default casting : only need to convert float to double */
4655 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4656 gen_cast(VT_DOUBLE
);
4657 } else if (arg
== NULL
) {
4658 error("too many arguments to function");
4660 gen_assign_cast(arg
->t
);
4667 int n
, t
, ft
, fc
, align
, size
, r
, data_offset
;
4672 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4675 } else if (tok
== TOK_CUINT
) {
4676 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4678 } else if (tok
== TOK_CLLONG
) {
4679 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4681 } else if (tok
== TOK_CULLONG
) {
4682 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4684 } else if (tok
== TOK_CFLOAT
) {
4685 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4687 } else if (tok
== TOK_CDOUBLE
) {
4688 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4690 } else if (tok
== TOK_CLDOUBLE
) {
4691 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4693 } else if (tok
== TOK___FUNC__
) {
4696 /* special function name identifier */
4698 len
= strlen(funcname
) + 1;
4699 /* generate char[len] type */
4700 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
4701 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4703 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
4704 ptr
= section_ptr_add(data_section
, len
);
4705 memcpy(ptr
, funcname
, len
);
4707 } else if (tok
== TOK_LSTR
) {
4710 } else if (tok
== TOK_STR
) {
4711 /* string parsing */
4714 type_size(t
, &align
);
4715 data_offset
= data_section
->data_offset
;
4716 data_offset
= (data_offset
+ align
- 1) & -align
;
4718 /* we must declare it as an array first to use initializer parser */
4719 t
= VT_ARRAY
| mk_pointer(t
);
4720 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4721 size
= type_size(t
, &align
);
4722 data_offset
+= size
;
4723 vpush_ref(t
, data_section
, fc
, size
);
4724 data_section
->data_offset
= data_offset
;
4730 if (parse_btype(&t
, &ad
)) {
4731 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4733 /* check ISOC99 compound literal */
4735 /* data is allocated locally by default */
4740 /* all except arrays are lvalues */
4741 if (!(ft
& VT_ARRAY
))
4742 r
|= lvalue_type(ft
);
4743 memset(&ad
, 0, sizeof(AttributeDef
));
4744 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4753 } else if (t
== '*') {
4756 } else if (t
== '&') {
4758 /* functions names must be treated as function pointers,
4759 except for unary '&' and sizeof. Since we consider that
4760 functions are not lvalues, we only have to handle it
4761 there and in function calls. */
4762 /* arrays can also be used although they are not lvalues */
4763 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4764 !(vtop
->t
& VT_ARRAY
))
4766 vtop
->t
= mk_pointer(vtop
->t
);
4771 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4772 vtop
->c
.i
= !vtop
->c
.i
;
4773 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4774 vtop
->c
.i
= vtop
->c
.i
^ 1;
4776 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4784 /* in order to force cast, we add zero */
4786 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
4787 error("pointer not accepted for unary plus");
4791 if (t
== TOK_SIZEOF
) {
4794 if (parse_btype(&t
, &ad
)) {
4795 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4797 /* XXX: some code could be generated: add eval
4809 vpushi(type_size(t
, &t
));
4811 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4814 } else if (t
== '-') {
4821 expect("identifier");
4825 error("'%s' undeclared", get_tok_str(t
, NULL
));
4826 /* for simple function calls, we tolerate undeclared
4827 external reference to int() function */
4828 s
= external_sym(t
, func_old_type
, 0);
4830 vset(s
->t
, s
->r
, s
->c
);
4831 /* if forward reference, we must point to s */
4832 if (vtop
->r
& VT_SYM
)
4837 /* post operations */
4839 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4842 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4844 if (tok
== TOK_ARROW
)
4849 /* expect pointer on structure */
4850 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4851 expect("struct or union");
4852 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4855 while ((s
= s
->next
) != NULL
) {
4860 error("field not found");
4861 /* add field offset to pointer */
4862 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4865 /* change type to field type, and set to lvalue */
4867 /* an array is never an lvalue */
4868 if (!(vtop
->t
& VT_ARRAY
))
4869 vtop
->r
|= lvalue_type(vtop
->t
);
4871 } else if (tok
== '[') {
4877 } else if (tok
== '(') {
4882 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4883 /* pointer test (no array accepted) */
4884 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4885 vtop
->t
= pointed_type(vtop
->t
);
4886 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4890 expect("function pointer");
4893 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4895 /* get return type */
4896 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4897 save_regs(0); /* save used temporary registers */
4898 gfunc_start(&gf
, s
->r
);
4900 sa
= s
->next
; /* first parameter */
4901 #ifdef INVERT_FUNC_PARAMS
4905 ParseState saved_parse_state
;
4908 /* read each argument and store it on a stack */
4909 /* XXX: merge it with macro args ? */
4915 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4919 else if (tok
== ')')
4921 tok_str_add_tok(&str
);
4924 tok_str_add(&str
, -1); /* end of file added */
4925 tok_str_add(&str
, 0);
4926 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4927 s1
->next
= sa
; /* add reference to argument */
4936 /* now generate code in reverse order by reading the stack */
4937 save_parse_state(&saved_parse_state
);
4939 macro_ptr
= (int *)args
->c
;
4943 expect("',' or ')'");
4944 gfunc_param_typed(&gf
, s
, args
->next
);
4946 free((int *)args
->c
);
4950 restore_parse_state(&saved_parse_state
);
4953 /* compute first implicit argument if a structure is returned */
4954 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4955 /* get some space for the returned structure */
4956 size
= type_size(s
->t
, &align
);
4957 loc
= (loc
- size
) & -align
;
4959 ret
.r
= VT_LOCAL
| VT_LVAL
;
4960 /* pass it as 'int' to avoid structure arg passing
4962 vset(VT_INT
, VT_LOCAL
, loc
);
4968 /* return in register */
4969 if (is_float(ret
.t
)) {
4972 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4978 #ifndef INVERT_FUNC_PARAMS
4982 gfunc_param_typed(&gf
, s
, sa
);
4992 error("too few arguments to function");
4996 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5010 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5011 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5012 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5035 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5036 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5037 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5038 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5039 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5040 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5041 (l
== 5 && tok
== '&') ||
5042 (l
== 6 && tok
== '^') ||
5043 (l
== 7 && tok
== '|') ||
5044 (l
== 8 && tok
== TOK_LAND
) ||
5045 (l
== 9 && tok
== TOK_LOR
)) {
5054 /* only used if non constant */
5062 if (tok
!= TOK_LAND
) {
5065 vset(VT_INT
, VT_JMPI
, t
);
5082 if (tok
!= TOK_LOR
) {
5085 vset(VT_INT
, VT_JMP
, t
);
5095 /* XXX: better constant handling */
5098 int t
, u
, c
, r1
, r2
, rc
;
5118 save_regs(1); /* we need to save all registers here except
5119 at the top because it is a branch point */
5122 /* XXX: long long handling ? */
5124 if (is_float(vtop
->t
))
5127 vtop
--; /* no vpop so that FP stack is not flushed */
5152 /* parse a constant expression and return value in vtop */
5153 void expr_const1(void)
5159 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5164 /* parse an integer constant and return its value */
5165 int expr_const(void)
5174 /* return the label token if current token is a label, otherwise
5181 /* fast test first */
5182 if (tok
< TOK_UIDENT
)
5184 /* no need to save tokc since we expect an identifier */
5192 /* XXX: may not work in all cases (macros ?) */
5201 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5206 /* generate line number info */
5208 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5209 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5211 last_line_num
= file
->line_num
;
5214 if (tok
== TOK_IF
) {
5221 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5223 if (c
== TOK_ELSE
) {
5227 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5228 gsym(d
); /* patch else jmp */
5231 } else if (tok
== TOK_WHILE
) {
5239 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5243 } else if (tok
== '{') {
5246 s
= local_stack
.top
;
5247 while (tok
!= '}') {
5250 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5252 /* pop locally defined symbols */
5253 sym_pop(&local_stack
, s
);
5255 } else if (tok
== TOK_RETURN
) {
5259 gen_assign_cast(func_vt
);
5260 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5261 /* if returning structure, must copy it to implicit
5262 first pointer arg location */
5263 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5266 /* copy structure value to pointer */
5268 } else if (is_float(func_vt
)) {
5273 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5276 rsym
= gjmp(rsym
); /* jmp */
5277 } else if (tok
== TOK_BREAK
) {
5280 error("cannot break");
5281 *bsym
= gjmp(*bsym
);
5284 } else if (tok
== TOK_CONTINUE
) {
5287 error("cannot continue");
5288 *csym
= gjmp(*csym
);
5291 } else if (tok
== TOK_FOR
) {
5318 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5323 if (tok
== TOK_DO
) {
5328 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5339 if (tok
== TOK_SWITCH
) {
5343 /* XXX: other types than integer */
5344 case_reg
= gv(RC_INT
);
5348 b
= gjmp(0); /* jump to first case */
5350 block(&a
, csym
, &b
, &c
, case_reg
);
5351 /* if no default, jmp after switch */
5359 if (tok
== TOK_CASE
) {
5366 if (gnu_ext
&& tok
== TOK_DOTS
) {
5370 warning("empty case range");
5372 /* since a case is like a label, we must skip it with a jmp */
5375 vset(VT_INT
, case_reg
, 0);
5379 *case_sym
= gtst(1, 0);
5382 *case_sym
= gtst(1, 0);
5383 vset(VT_INT
, case_reg
, 0);
5386 *case_sym
= gtst(1, *case_sym
);
5390 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5392 if (tok
== TOK_DEFAULT
) {
5398 error("too many 'default'");
5400 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5402 if (tok
== TOK_GOTO
) {
5404 s
= sym_find1(&label_stack
, tok
);
5405 /* put forward definition if needed */
5407 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5408 /* label already defined */
5409 if (s
->t
& LABEL_FORWARD
)
5419 s
= sym_find1(&label_stack
, b
);
5421 if (!(s
->t
& LABEL_FORWARD
))
5422 error("multiple defined label");
5427 sym_push1(&label_stack
, b
, 0, ind
);
5429 /* we accept this, but it is a mistake */
5431 warning("deprecated use of label at end of compound statement");
5433 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5435 /* expression case */
5445 /* t is the array or struct type. c is the array or struct
5446 address. cur_index/cur_field is the pointer to the current
5447 value. 'size_only' is true if only size info is needed (only used
5449 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5450 int *cur_index
, Sym
**cur_field
,
5454 int notfirst
, index
, align
, l
;
5457 if (gnu_ext
&& (l
= is_label()) != 0)
5460 while (tok
== '[' || tok
== '.') {
5462 if (!(t
& VT_ARRAY
))
5463 expect("array type");
5464 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5466 index
= expr_const();
5467 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5468 expect("invalid index");
5472 t
= pointed_type(t
);
5473 c
+= index
* type_size(t
, &align
);
5479 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5480 expect("struct/union type");
5481 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5493 t
= f
->t
| (t
& ~VT_TYPE
);
5508 t
= pointed_type(t
);
5509 c
+= index
* type_size(t
, &align
);
5513 error("too many field init");
5514 t
= f
->t
| (t
& ~VT_TYPE
);
5518 decl_initializer(t
, sec
, c
, 0, size_only
);
5522 #define EXPR_CONST 1
5525 /* store a value or an expression directly in global data or in local array */
5526 void init_putv(int t
, Section
*sec
, unsigned long c
,
5527 int v
, int expr_type
)
5529 int saved_global_expr
, bt
;
5537 /* compound literals must be allocated globally in this case */
5538 saved_global_expr
= global_expr
;
5541 global_expr
= saved_global_expr
;
5549 /* XXX: not portable */
5550 /* XXX: generate error if incorrect relocation */
5553 ptr
= sec
->data
+ c
;
5554 if ((vtop
->r
& VT_SYM
) &&
5560 error("initializer element is not computable at load time");
5563 *(char *)ptr
= vtop
->c
.i
;
5566 *(short *)ptr
= vtop
->c
.i
;
5569 *(double *)ptr
= vtop
->c
.d
;
5572 *(long double *)ptr
= vtop
->c
.ld
;
5575 *(long long *)ptr
= vtop
->c
.ll
;
5578 if (vtop
->r
& VT_SYM
) {
5579 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5582 *(int *)ptr
= vtop
->c
.i
;
5588 vset(t
, VT_LOCAL
, c
);
5595 /* put zeros for variable based init */
5596 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5601 /* nothing to do because globals are already set to zero */
5603 gfunc_start(&gf
, FUNC_CDECL
);
5608 vset(VT_INT
, VT_LOCAL
, c
);
5610 vpush_sym(func_old_type
, TOK_memset
);
5615 /* 't' contains the type and storage info. 'c' is the offset of the
5616 object in section 'sec'. If 'sec' is NULL, it means stack based
5617 allocation. 'first' is true if array '{' must be read (multi
5618 dimension implicit array init handling). 'size_only' is true if
5619 size only evaluation is wanted (only for arrays). */
5620 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5622 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5623 int t1
, size1
, align1
, expr_type
;
5628 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5631 t1
= pointed_type(t
);
5632 size1
= type_size(t1
, &align1
);
5635 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5641 /* only parse strings here if correct type (otherwise: handle
5642 them as ((w)char *) expressions */
5643 if ((tok
== TOK_LSTR
&&
5644 (t1
& VT_BTYPE
) == VT_INT
) ||
5646 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5647 /* XXX: move multiple string parsing in parser ? */
5648 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5650 /* compute maximum number of chars wanted */
5652 if (n
>= 0 && nb
> (n
- array_length
))
5653 nb
= n
- array_length
;
5656 warning("initializer-string for array is too long");
5658 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5659 ts
->str
[i
], EXPR_VAL
);
5665 /* only add trailing zero if enough storage (no
5666 warning in this case since it is standard) */
5667 if (n
< 0 || array_length
< n
) {
5669 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5675 while (tok
!= '}') {
5676 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5677 if (n
>= 0 && index
>= n
)
5678 error("index too large");
5679 /* must put zero in holes (note that doing it that way
5680 ensures that it even works with designators) */
5681 if (!size_only
&& array_length
< index
) {
5682 init_putz(t1
, sec
, c
+ array_length
* size1
,
5683 (index
- array_length
) * size1
);
5686 if (index
> array_length
)
5687 array_length
= index
;
5688 /* special test for multi dimensional arrays (may not
5689 be strictly correct if designators are used at the
5691 if (index
>= n
&& no_oblock
)
5700 /* put zeros at the end */
5701 if (!size_only
&& n
>= 0 && array_length
< n
) {
5702 init_putz(t1
, sec
, c
+ array_length
* size1
,
5703 (n
- array_length
) * size1
);
5705 /* patch type size if needed */
5707 s
->c
= array_length
;
5708 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5709 /* XXX: union needs only one init */
5711 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5716 while (tok
!= '}') {
5717 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5718 /* fill with zero between fields */
5720 if (!size_only
&& array_length
< index
) {
5721 init_putz(t
, sec
, c
+ array_length
,
5722 index
- array_length
);
5724 index
= index
+ type_size(f
->t
, &align1
);
5725 if (index
> array_length
)
5726 array_length
= index
;
5732 /* put zeros at the end */
5733 if (!size_only
&& array_length
< n
) {
5734 init_putz(t
, sec
, c
+ array_length
,
5738 } else if (tok
== '{') {
5740 decl_initializer(t
, sec
, c
, first
, size_only
);
5742 } else if (size_only
) {
5743 /* just skip expression */
5745 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5749 else if (tok
== ')')
5754 /* currently, we always use constant expression for globals
5755 (may change for scripting case) */
5756 expr_type
= EXPR_CONST
;
5758 expr_type
= EXPR_ANY
;
5759 init_putv(t
, sec
, c
, 0, expr_type
);
5763 /* parse an initializer for type 't' if 'has_init' is true, and
5764 allocate space in local or global data space ('r' is either
5765 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5766 variable 'v' of scope 'scope' is declared before initializers are
5767 parsed. If 'v' is zero, then a reference to the new object is put
5768 in the value stack. */
5769 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5772 int size
, align
, addr
, data_offset
;
5774 ParseState saved_parse_state
;
5775 TokenString init_str
;
5778 size
= type_size(t
, &align
);
5779 /* If unknown size, we must evaluate it before
5780 evaluating initializers because
5781 initializers can generate global data too
5782 (e.g. string pointers or ISOC99 compound
5783 literals). It also simplifies local
5784 initializers handling */
5785 tok_str_new(&init_str
);
5788 error("unknown type size");
5789 /* get all init string */
5791 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5793 error("unexpected end of file in initializer");
5794 tok_str_add_tok(&init_str
);
5797 else if (tok
== '}') {
5804 tok_str_add(&init_str
, -1);
5805 tok_str_add(&init_str
, 0);
5808 save_parse_state(&saved_parse_state
);
5810 macro_ptr
= init_str
.str
;
5812 decl_initializer(t
, NULL
, 0, 1, 1);
5813 /* prepare second initializer parsing */
5814 macro_ptr
= init_str
.str
;
5817 /* if still unknown size, error */
5818 size
= type_size(t
, &align
);
5820 error("unknown type size");
5822 /* take into account specified alignment if bigger */
5823 if (ad
->aligned
> align
)
5824 align
= ad
->aligned
;
5825 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5827 if (do_bounds_check
&& (t
& VT_ARRAY
))
5829 #ifdef TCC_TARGET_IL
5830 /* XXX: ugly patch to allocate local variables for IL, just
5835 loc
= (loc
- size
) & -align
;
5838 /* handles bounds */
5839 /* XXX: currently, since we do only one pass, we cannot track
5840 '&' operators, so we add only arrays */
5841 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5842 unsigned long *bounds_ptr
;
5843 /* add padding between regions */
5845 /* then add local bound info */
5846 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
5847 bounds_ptr
[0] = addr
;
5848 bounds_ptr
[1] = size
;
5851 /* compute section */
5859 data_offset
= sec
->data_offset
;
5860 data_offset
= (data_offset
+ align
- 1) & -align
;
5862 /* very important to increment global pointer at this time
5863 because initializers themselves can create new initializers */
5864 data_offset
+= size
;
5865 /* add padding if bound check */
5866 if (do_bounds_check
)
5868 sec
->data_offset
= data_offset
;
5872 /* local variable */
5873 sym_push(v
, t
, r
, addr
);
5875 /* push local reference */
5882 if (scope
== VT_CONST
) {
5883 /* global scope: see if already defined */
5887 if (!is_compatible_types(sym
->t
, t
))
5888 error("incompatible types for redefinition of '%s'",
5889 get_tok_str(v
, NULL
));
5890 if (!(sym
->t
& VT_EXTERN
))
5891 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5892 sym
->t
&= ~VT_EXTERN
;
5895 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5897 put_extern_sym(sym
, sec
, addr
, size
);
5901 /* push global reference */
5902 sym
= get_sym_ref(t
, sec
, addr
, size
);
5904 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
5907 /* handles bounds now because the symbol must be defined
5908 before for the relocation */
5909 if (do_bounds_check
) {
5910 unsigned long *bounds_ptr
;
5912 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
5913 /* then add global bound info */
5914 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
5915 bounds_ptr
[0] = 0; /* relocated */
5916 bounds_ptr
[1] = size
;
5920 decl_initializer(t
, sec
, addr
, 1, 0);
5921 /* restore parse state if needed */
5924 restore_parse_state(&saved_parse_state
);
5929 void put_func_debug(Sym
*sym
)
5934 /* XXX: we put here a dummy type */
5935 snprintf(buf
, sizeof(buf
), "%s:%c1",
5936 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
5937 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
5938 cur_text_section
, sym
->c
);
5943 /* not finished : try to put some local vars in registers */
5944 //#define CONFIG_REG_VARS
5946 #ifdef CONFIG_REG_VARS
5947 void add_var_ref(int t
)
5949 printf("%s:%d: &%s\n",
5950 file
->filename
, file
->line_num
,
5951 get_tok_str(t
, NULL
));
5954 /* first pass on a function with heuristic to extract variable usage
5955 and pointer references to local variables for register allocation */
5956 void analyse_function(void)
5963 /* any symbol coming after '&' is considered as being a
5964 variable whose reference is taken. It is highly unaccurate
5965 but it is difficult to do better without a complete parse */
5968 /* if '& number', then no need to examine next tokens */
5969 if (tok
== TOK_CINT
||
5971 tok
== TOK_CLLONG
||
5972 tok
== TOK_CULLONG
) {
5974 } else if (tok
>= TOK_UIDENT
) {
5975 /* if '& ident [' or '& ident ->', then ident address
5979 if (tok
!= '[' && tok
!= TOK_ARROW
)
5983 while (tok
!= '}' && tok
!= ';' &&
5984 !((tok
== ',' || tok
== ')') && level
== 0)) {
5985 if (tok
>= TOK_UIDENT
) {
5987 } else if (tok
== '(') {
5989 } else if (tok
== ')') {
6002 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6005 int t
, b
, v
, has_init
, r
;
6010 if (!parse_btype(&b
, &ad
)) {
6011 /* skip redundant ';' */
6012 /* XXX: find more elegant solution */
6017 /* special test for old K&R protos without explicit int
6018 type. Only accepted when defining global data */
6019 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6023 if (((b
& VT_BTYPE
) == VT_ENUM
||
6024 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6026 /* we accept no variable after */
6030 while (1) { /* iterate thru each declaration */
6031 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6035 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6036 printf("type = '%s'\n", buf
);
6040 #ifdef CONFIG_REG_VARS
6041 TokenString func_str
;
6042 ParseState saved_parse_state
;
6047 error("cannot use local functions");
6049 expect("function definition");
6051 #ifdef CONFIG_REG_VARS
6052 /* parse all function code and record it */
6054 tok_str_new(&func_str
);
6060 error("unexpected end of file");
6061 tok_str_add_tok(&func_str
);
6066 } else if (t
== '}') {
6068 if (block_level
== 0)
6072 tok_str_add(&func_str
, -1);
6073 tok_str_add(&func_str
, 0);
6075 save_parse_state(&saved_parse_state
);
6077 macro_ptr
= func_str
.str
;
6082 /* compute text section */
6083 cur_text_section
= ad
.section
;
6084 if (!cur_text_section
)
6085 cur_text_section
= text_section
;
6086 ind
= cur_text_section
->data_offset
;
6087 funcname
= get_tok_str(v
, NULL
);
6090 /* if symbol is already defined, then put complete type */
6093 /* put function symbol */
6094 sym
= sym_push1(&global_stack
, v
, t
, 0);
6096 /* NOTE: we patch the symbol size later */
6097 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6099 sym
->r
= VT_SYM
| VT_CONST
;
6100 /* put debug symbol */
6102 put_func_debug(sym
);
6103 /* push a dummy symbol to enable local sym storage */
6104 sym_push1(&local_stack
, 0, 0, 0);
6108 #ifdef CONFIG_REG_VARS
6109 macro_ptr
= func_str
.str
;
6112 block(NULL
, NULL
, NULL
, NULL
, 0);
6115 cur_text_section
->data_offset
= ind
;
6116 sym_pop(&label_stack
, NULL
); /* reset label stack */
6117 sym_pop(&local_stack
, NULL
); /* reset local stack */
6118 /* end of function */
6119 /* patch symbol size */
6120 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
6123 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6125 funcname
= ""; /* for safety */
6126 func_vt
= VT_VOID
; /* for safety */
6127 ind
= 0; /* for safety */
6129 #ifdef CONFIG_REG_VARS
6131 restore_parse_state(&saved_parse_state
);
6135 if (b
& VT_TYPEDEF
) {
6136 /* save typedefed type */
6137 /* XXX: test storage specifiers ? */
6138 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6139 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6140 /* external function definition */
6141 external_sym(v
, t
, 0);
6143 /* not lvalue if array */
6145 if (!(t
& VT_ARRAY
))
6146 r
|= lvalue_type(t
);
6147 if (b
& VT_EXTERN
) {
6148 /* external variable */
6149 external_sym(v
, t
, r
);
6155 has_init
= (tok
== '=');
6158 decl_initializer_alloc(t
, &ad
, r
,
6172 /* compile the C file opened in 'file'. Return non zero if errors. */
6173 static int tcc_compile(TCCState
*s
)
6180 include_stack_ptr
= include_stack
;
6181 ifdef_stack_ptr
= ifdef_stack
;
6184 anon_sym
= SYM_FIRST_ANOM
;
6186 /* file info: full path + filename */
6187 section_sym
= 0; /* avoid warning */
6189 section_sym
= put_elf_sym(symtab_section
, 0, 0,
6190 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
6191 text_section
->sh_num
, NULL
);
6192 getcwd(buf
, sizeof(buf
));
6193 pstrcat(buf
, sizeof(buf
), "/");
6194 put_stabs_r(buf
, N_SO
, 0, 0,
6195 text_section
->data_offset
, text_section
, section_sym
);
6196 put_stabs_r(file
->filename
, N_SO
, 0, 0,
6197 text_section
->data_offset
, text_section
, section_sym
);
6199 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6200 symbols can be safely used */
6201 put_elf_sym(symtab_section
, 0, 0,
6202 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6203 SHN_ABS
, file
->filename
);
6205 /* define common 'char *' type because it is often used internally
6206 for arrays and struct dereference */
6207 char_pointer_type
= mk_pointer(VT_BYTE
);
6208 /* define an old type function 'int func()' */
6210 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
6211 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6213 define_start
= define_stack
.top
;
6215 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6219 expect("declaration");
6221 /* end of translation unit info */
6223 put_stabs_r(NULL
, N_SO
, 0, 0,
6224 text_section
->data_offset
, text_section
, section_sym
);
6227 /* reset define stack, but leave -Dsymbols (may be incorrect if
6228 they are undefined) */
6229 sym_pop(&define_stack
, define_start
);
6231 sym_pop(&global_stack
, NULL
);
6236 int tcc_compile_string(TCCState
*s
, const char *str
)
6238 BufferedFile bf1
, *bf
= &bf1
;
6241 /* init file structure */
6243 bf
->buf_ptr
= (char *)str
;
6244 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6245 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6249 ret
= tcc_compile(s
);
6251 /* currently, no need to close */
6255 /* define a symbol. A value can also be provided with the '=' operator */
6256 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6258 BufferedFile bf1
, *bf
= &bf1
;
6260 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6261 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6265 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6267 /* init file structure */
6269 bf
->buf_ptr
= bf
->buffer
;
6270 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6271 bf
->filename
[0] = '\0';
6275 include_stack_ptr
= include_stack
;
6277 /* parse with define parser */
6279 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6285 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6289 ts
= tok_alloc(sym
, 0);
6290 s
= sym_find1(&define_stack
, tok
);
6291 /* undefine symbol by putting an invalid name */
6293 sym_undef(&define_stack
, s
);
6296 static int put_elf_str(Section
*s
, const char *sym
)
6301 len
= strlen(sym
) + 1;
6302 offset
= s
->data_offset
;
6303 ptr
= section_ptr_add(s
, len
);
6304 memcpy(ptr
, sym
, len
);
6308 /* elf symbol hashing function */
6309 static unsigned long elf_hash(const unsigned char *name
)
6311 unsigned long h
= 0, g
;
6314 h
= (h
<< 4) + *name
++;
6323 /* rebuild hash table of section s */
6324 /* NOTE: we do factorize the hash table code to go faster */
6325 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
6328 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
6331 strtab
= s
->link
->data
;
6332 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
6334 s
->hash
->data_offset
= 0;
6335 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
6336 ptr
[0] = nb_buckets
;
6340 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
6341 ptr
+= nb_buckets
+ 1;
6343 sym
= (Elf32_Sym
*)s
->data
+ 1;
6344 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
6345 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
6346 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
6348 hash
[h
] = sym_index
;
6357 /* return the symbol number */
6358 static int put_elf_sym(Section
*s
,
6359 unsigned long value
, unsigned long size
,
6360 int info
, int other
, int shndx
, const char *name
)
6362 int name_offset
, sym_index
;
6367 sym
= section_ptr_add(s
, sizeof(Elf32_Sym
));
6369 name_offset
= put_elf_str(s
->link
, name
);
6372 /* XXX: endianness */
6373 sym
->st_name
= name_offset
;
6374 sym
->st_value
= value
;
6375 sym
->st_size
= size
;
6376 sym
->st_info
= info
;
6377 sym
->st_other
= other
;
6378 sym
->st_shndx
= shndx
;
6379 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6383 ptr
= section_ptr_add(hs
, sizeof(int));
6384 base
= (int *)hs
->data
;
6385 /* only add global or weak symbols */
6386 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
6387 /* add another hashing entry */
6389 h
= elf_hash(name
) % nbuckets
;
6391 base
[2 + h
] = sym_index
;
6393 /* we resize the hash table */
6394 hs
->nb_hashed_syms
++;
6395 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
6396 rebuild_hash(s
, 2 * nbuckets
);
6406 /* find global ELF symbol 'name' and return its index. Return 0 if not
6408 static int find_elf_sym(Section
*s
, const char *name
)
6412 int nbuckets
, sym_index
, h
;
6418 nbuckets
= ((int *)hs
->data
)[0];
6419 h
= elf_hash(name
) % nbuckets
;
6420 sym_index
= ((int *)hs
->data
)[2 + h
];
6421 while (sym_index
!= 0) {
6422 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6423 name1
= s
->link
->data
+ sym
->st_name
;
6424 if (!strcmp(name
, name1
))
6426 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6431 /* return elf symbol value or error */
6432 static unsigned long get_elf_sym_val(const char *name
)
6437 sym_index
= find_elf_sym(symtab_section
, name
);
6439 error("%s not defined", name
);
6440 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6441 return sym
->st_value
;
6444 /* add an elf symbol : check if it is already defined and patch
6445 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
6446 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
6447 int info
, int sh_num
, const char *name
)
6450 int sym_bind
, sym_index
, sym_type
, esym_bind
;
6452 sym_bind
= ELF32_ST_BIND(info
);
6453 sym_type
= ELF32_ST_TYPE(info
);
6455 if (sym_bind
!= STB_LOCAL
) {
6456 /* we search global or weak symbols */
6457 sym_index
= find_elf_sym(s
, name
);
6460 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6461 if (esym
->st_shndx
!= SHN_UNDEF
) {
6462 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
6463 if (sh_num
== SHN_UNDEF
) {
6464 /* ignore adding of undefined symbol if the
6465 corresponding symbol is already defined */
6466 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
6467 /* global overrides weak, so patch */
6469 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
6470 /* weak is ignored if already global */
6473 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
6474 sym_bind
, sh_num
, esym_bind
, esym
->st_shndx
);
6476 /* NOTE: we accept that two DLL define the same symbol */
6477 if (s
!= dynsymtab_section
)
6478 error("'%s' defined twice", name
);
6482 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6483 esym
->st_shndx
= sh_num
;
6484 esym
->st_value
= value
;
6485 esym
->st_size
= size
;
6489 sym_index
= put_elf_sym(s
, value
, size
,
6490 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6496 /* update sym->c so that it points to an external symbol in section
6497 'section' with value 'value' */
6498 static void put_extern_sym(Sym
*sym
, Section
*section
,
6499 unsigned long value
, unsigned long size
)
6501 int sym_type
, sym_bind
, sh_num
, info
;
6507 sh_num
= section
->sh_num
;
6511 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6512 sym_type
= STT_FUNC
;
6514 sym_type
= STT_OBJECT
;
6515 if (sym
->t
& VT_STATIC
)
6516 sym_bind
= STB_LOCAL
;
6518 sym_bind
= STB_GLOBAL
;
6520 name
= get_tok_str(sym
->v
, NULL
);
6521 #ifdef CONFIG_TCC_BCHECK
6522 if (do_bounds_check
) {
6523 /* if bound checking is activated, we change some function
6524 names by adding the "__bound" prefix */
6536 strcpy(buf
, "__bound_");
6543 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
6544 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
6546 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6547 esym
->st_value
= value
;
6548 esym
->st_size
= size
;
6549 esym
->st_shndx
= sh_num
;
6553 /* put relocation */
6554 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
6555 int type
, int symbol
)
6563 /* if no relocation section, create it */
6564 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6565 /* if the symtab is allocated, then we consider the relocation
6567 sr
= new_section(buf
, SHT_REL
, symtab
->sh_flags
);
6568 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6570 sr
->sh_info
= s
->sh_num
;
6573 rel
= section_ptr_add(sr
, sizeof(Elf32_Rel
));
6574 rel
->r_offset
= offset
;
6575 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6578 /* put stab debug information */
6581 unsigned long n_strx
; /* index into string table of name */
6582 unsigned char n_type
; /* type of symbol */
6583 unsigned char n_other
; /* misc info (usually empty) */
6584 unsigned short n_desc
; /* description field */
6585 unsigned long n_value
; /* value of symbol */
6588 static void put_stabs(const char *str
, int type
, int other
, int desc
,
6589 unsigned long value
)
6593 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
6595 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6600 sym
->n_other
= other
;
6602 sym
->n_value
= value
;
6605 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
6606 unsigned long value
, Section
*sec
, int sym_index
)
6608 put_stabs(str
, type
, other
, desc
, value
);
6609 put_elf_reloc(symtab_section
, stab_section
,
6610 stab_section
->data_offset
- sizeof(unsigned long),
6611 R_DATA_32
, sym_index
);
6614 static void put_stabn(int type
, int other
, int desc
, int value
)
6616 put_stabs(NULL
, type
, other
, desc
, value
);
6619 static void put_stabd(int type
, int other
, int desc
)
6621 put_stabs(NULL
, type
, other
, desc
, 0);
6624 /* In an ELF file symbol table, the local symbols must appear below
6625 the global and weak ones. Since TCC cannot sort it while generating
6626 the code, we must do it after. All the relocation tables are also
6627 modified to take into account the symbol table sorting */
6628 static void sort_syms(Section
*s
)
6630 int *old_to_new_syms
;
6631 Elf32_Sym
*new_syms
;
6634 Elf32_Rel
*rel
, *rel_end
;
6636 int type
, sym_index
;
6638 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
6639 new_syms
= malloc(nb_syms
* sizeof(Elf32_Sym
));
6641 error("memory full");
6642 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
6643 if (!old_to_new_syms
)
6644 error("memory full");
6645 /* first pass for local symbols */
6646 p
= (Elf32_Sym
*)s
->data
;
6648 for(i
= 0; i
< nb_syms
; i
++) {
6649 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
6650 old_to_new_syms
[i
] = q
- new_syms
;
6655 /* save the number of local symbols in section header */
6656 s
->sh_info
= q
- new_syms
;
6658 /* then second pass for non local symbols */
6659 p
= (Elf32_Sym
*)s
->data
;
6660 for(i
= 0; i
< nb_syms
; i
++) {
6661 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
6662 old_to_new_syms
[i
] = q
- new_syms
;
6668 /* we copy the new symbols to the old */
6669 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
6672 /* now we modify all the relocations */
6673 for(i
= 1; i
< nb_sections
; i
++) {
6675 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
6676 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6677 for(rel
= (Elf32_Rel
*)sr
->data
;
6680 sym_index
= ELF32_R_SYM(rel
->r_info
);
6681 type
= ELF32_R_TYPE(rel
->r_info
);
6682 sym_index
= old_to_new_syms
[sym_index
];
6683 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
6688 free(old_to_new_syms
);
6691 /* relocate common symbols in the .bss section */
6692 static void relocate_common_syms(void)
6694 Elf32_Sym
*sym
, *sym_end
;
6695 unsigned long offset
, align
;
6697 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
6698 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6701 if (sym
->st_shndx
== SHN_COMMON
) {
6703 align
= sym
->st_value
;
6704 offset
= bss_section
->data_offset
;
6705 offset
= (offset
+ align
- 1) & -align
;
6706 sym
->st_value
= offset
;
6707 sym
->st_shndx
= bss_section
->sh_num
;
6708 offset
+= sym
->st_size
;
6709 bss_section
->data_offset
= offset
;
6714 static void *resolve_sym(const char *sym
)
6716 return dlsym(NULL
, sym
);
6719 /* relocate symbol table, resolve undefined symbols if do_resolve is
6720 true and output error if undefined symbol. */
6721 static void relocate_syms(int do_resolve
)
6723 Elf32_Sym
*sym
, *esym
, *sym_end
;
6724 int sym_bind
, sh_num
, sym_index
;
6728 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
6729 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6732 sh_num
= sym
->st_shndx
;
6733 if (sh_num
== SHN_UNDEF
) {
6734 name
= strtab_section
->data
+ sym
->st_name
;
6736 name
= symtab_section
->link
->data
+ sym
->st_name
;
6737 addr
= (unsigned long)resolve_sym(name
);
6739 sym
->st_value
= addr
;
6742 } else if (dynsym
) {
6743 /* if dynamic symbol exist, then use it */
6744 sym_index
= find_elf_sym(dynsym
, name
);
6746 esym
= &((Elf32_Sym
*)dynsym
->data
)[sym_index
];
6747 sym
->st_value
= esym
->st_value
;
6751 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
6753 if (!strcmp(name
, "_fp_hw"))
6755 /* only weak symbols are accepted to be undefined. Their
6757 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
6758 if (sym_bind
== STB_WEAK
) {
6761 error("undefined symbol '%s'", name
);
6763 } else if (sh_num
< SHN_LORESERVE
) {
6764 /* add section base */
6765 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
6771 /* relocate a given section (CPU dependant) */
6772 static void relocate_section(TCCState
*s1
, Section
*s
)
6775 Elf32_Rel
*rel
, *rel_end
, *qrel
;
6777 int type
, sym_index
, esym_index
;
6779 unsigned long val
, addr
;
6782 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6783 qrel
= (Elf32_Rel
*)sr
->data
;
6787 ptr
= s
->data
+ rel
->r_offset
;
6789 sym_index
= ELF32_R_SYM(rel
->r_info
);
6790 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6791 val
= sym
->st_value
;
6792 type
= ELF32_R_TYPE(rel
->r_info
);
6793 addr
= s
->sh_addr
+ rel
->r_offset
;
6798 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
6799 esym_index
= symtab_to_dynsym
[sym_index
];
6800 qrel
->r_offset
= rel
->r_offset
;
6802 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_32
);
6806 qrel
->r_info
= ELF32_R_INFO(0, R_386_RELATIVE
);
6813 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
6814 /* DLL relocation */
6815 esym_index
= symtab_to_dynsym
[sym_index
];
6817 qrel
->r_offset
= rel
->r_offset
;
6818 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_PC32
);
6823 *(int *)ptr
+= val
- addr
;
6826 *(int *)ptr
+= val
- addr
;
6828 case R_386_GLOB_DAT
:
6829 case R_386_JMP_SLOT
:
6833 *(int *)ptr
+= got
->sh_addr
- addr
;
6836 *(int *)ptr
+= val
- got
->sh_addr
;
6839 /* we load the got offset */
6840 *(int *)ptr
+= got_offsets
[sym_index
];
6844 /* if the relocation is allocated, we change its symbol table */
6845 if (sr
->sh_flags
& SHF_ALLOC
)
6849 /* relocate relocation table in 'sr' */
6850 static void relocate_rel(Section
*sr
)
6853 Elf32_Rel
*rel
, *rel_end
;
6855 s
= sections
[sr
->sh_info
];
6856 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6857 for(rel
= (Elf32_Rel
*)sr
->data
;
6860 rel
->r_offset
+= s
->sh_addr
;
6864 /* count the number of dynamic relocations so that we can reserve
6866 static int prepare_dynamic_rel(Section
*sr
)
6868 Elf32_Rel
*rel
, *rel_end
;
6869 int sym_index
, esym_index
, type
, count
;
6872 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
6873 for(rel
= (Elf32_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
6874 sym_index
= ELF32_R_SYM(rel
->r_info
);
6875 type
= ELF32_R_TYPE(rel
->r_info
);
6881 esym_index
= symtab_to_dynsym
[sym_index
];
6890 /* allocate the section */
6891 sr
->sh_flags
|= SHF_ALLOC
;
6892 sr
->sh_size
= count
* sizeof(Elf32_Rel
);
6897 static void put_got_offset(int index
, unsigned long val
)
6902 if (index
>= nb_got_offsets
) {
6903 /* find immediately bigger power of 2 and reallocate array */
6907 tab
= realloc(got_offsets
, n
* sizeof(unsigned long));
6909 error("memory full");
6911 memset(got_offsets
+ nb_got_offsets
, 0,
6912 (n
- nb_got_offsets
) * sizeof(unsigned long));
6915 got_offsets
[index
] = val
;
6918 /* XXX: suppress that */
6919 static void put32(unsigned char *p
, unsigned int val
)
6927 static void build_got(void)
6931 /* if no got, then create it */
6932 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6933 got
->sh_entsize
= 4;
6934 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
6935 got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
6936 ptr
= section_ptr_add(got
, 3 * sizeof(int));
6937 /* keep space for _DYNAMIC pointer, if present */
6939 /* two dummy got entries */
6944 /* put a got entry corresponding to a symbol in symtab_section. 'size'
6945 and 'info' can be modifed if more precise info comes from the DLL */
6946 static void put_got_entry(int reloc_type
, unsigned long size
, int info
,
6952 unsigned long offset
;
6958 /* if a got entry already exists for that symbol, no need to add one */
6959 if (sym_index
< nb_got_offsets
&&
6960 got_offsets
[sym_index
] != 0)
6963 put_got_offset(sym_index
, got
->data_offset
);
6966 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6967 name
= symtab_section
->link
->data
+ sym
->st_name
;
6968 offset
= sym
->st_value
;
6969 /* NOTE: we put temporarily the got offset */
6970 if (reloc_type
== R_386_JMP_SLOT
) {
6972 offset
= got
->data_offset
;
6974 index
= put_elf_sym(dynsym
, offset
,
6975 size
, info
, 0, sym
->st_shndx
, name
);
6976 /* put a got entry */
6977 put_elf_reloc(dynsym
, got
,
6981 ptr
= section_ptr_add(got
, sizeof(int));
6985 /* build GOT and PLT entries */
6986 static void build_got_entries(void)
6988 Section
*s
, *symtab
;
6989 Elf32_Rel
*rel
, *rel_end
;
6991 int i
, type
, reloc_type
, sym_index
;
6993 for(i
= 1; i
< nb_sections
; i
++) {
6995 if (s
->sh_type
!= SHT_REL
)
6997 /* no need to handle got relocations */
6998 if (s
->link
!= symtab_section
)
7001 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
7002 for(rel
= (Elf32_Rel
*)s
->data
;
7005 type
= ELF32_R_TYPE(rel
->r_info
);
7013 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
7014 sym_index
= ELF32_R_SYM(rel
->r_info
);
7015 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
7016 /* look at the symbol got offset. If none, then add one */
7017 if (type
== R_386_GOT32
)
7018 reloc_type
= R_386_GLOB_DAT
;
7020 reloc_type
= R_386_JMP_SLOT
;
7021 put_got_entry(reloc_type
, sym
->st_size
, sym
->st_info
,
7032 static Section
*new_symtab(const char *symtab_name
, int sh_type
, int sh_flags
,
7033 const char *strtab_name
,
7034 const char *hash_name
, int hash_sh_flags
)
7036 Section
*symtab
, *strtab
, *hash
;
7037 int *ptr
, nb_buckets
;
7039 symtab
= new_section(symtab_name
, sh_type
, sh_flags
);
7040 symtab
->sh_entsize
= sizeof(Elf32_Sym
);
7041 strtab
= new_section(strtab_name
, SHT_STRTAB
, sh_flags
);
7042 put_elf_str(strtab
, "");
7043 symtab
->link
= strtab
;
7044 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
7048 hash
= new_section(hash_name
, SHT_HASH
, hash_sh_flags
);
7049 hash
->sh_entsize
= sizeof(int);
7050 symtab
->hash
= hash
;
7051 hash
->link
= symtab
;
7053 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
7054 ptr
[0] = nb_buckets
;
7056 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
7060 /* put dynamic tag */
7061 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
7064 dyn
= section_ptr_add(dynamic
, sizeof(Elf32_Dyn
));
7066 dyn
->d_un
.d_val
= val
;
7069 /* add tcc runtime libraries */
7070 static void tcc_add_runtime(TCCState
*s1
)
7077 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.o");
7078 tcc_add_file(s1
, buf
);
7079 #ifdef CONFIG_TCC_BCHECK
7080 if (do_bounds_check
) {
7081 /* XXX: add an object file to do that */
7082 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
7084 add_elf_sym(symtab_section
, 0, 0,
7085 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7086 bounds_section
->sh_num
, "__bounds_start");
7087 add_elf_sym(symtab_section
, (long)&rt_error
, 0,
7088 ELF32_ST_INFO(STB_GLOBAL
, STT_FUNC
),
7089 SHN_ABS
, "rt_error");
7090 /* add bound check code */
7091 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
7092 tcc_add_file(s1
, buf
);
7095 /* add libc if not memory output */
7096 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
7097 tcc_add_library(s1
, "c");
7098 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
7100 /* add various standard linker symbols */
7101 add_elf_sym(symtab_section
,
7102 text_section
->data_offset
, 0,
7103 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7104 text_section
->sh_num
, "_etext");
7105 add_elf_sym(symtab_section
,
7106 data_section
->data_offset
, 0,
7107 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7108 data_section
->sh_num
, "_edata");
7109 add_elf_sym(symtab_section
,
7110 bss_section
->data_offset
, 0,
7111 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7112 bss_section
->sh_num
, "_end");
7113 /* add start and stop symbols for sections whose name can be
7115 for(i
= 1; i
< nb_sections
; i
++) {
7117 if (s
->sh_type
== SHT_PROGBITS
&&
7118 (s
->sh_flags
& SHF_ALLOC
)) {
7122 /* check if section name can be expressed in C */
7128 if (!isid(ch
) && !isnum(ch
))
7132 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
7133 add_elf_sym(symtab_section
,
7135 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7137 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
7138 add_elf_sym(symtab_section
,
7140 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7147 /* add dynamic sections so that the executable is dynamically linked */
7148 static char elf_interp
[] = "/lib/ld-linux.so.2";
7150 #define ELF_START_ADDR 0x08048000
7151 #define ELF_PAGE_SIZE 0x1000
7153 /* output an ELF file */
7154 /* XXX: handle realloc'ed sections (instead of mmaping them) */
7155 /* XXX: suppress unneeded sections */
7156 int tcc_output_file(TCCState
*s1
, const char *filename
)
7162 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
7164 Section
*strsec
, *s
;
7165 Elf32_Shdr shdr
, *sh
;
7166 Elf32_Phdr
*phdr
, *ph
;
7167 Section
*interp
, *plt
, *dynamic
, *dynstr
;
7168 unsigned long saved_dynamic_data_offset
;
7170 int type
, file_type
;
7171 unsigned long rel_addr
, rel_size
;
7173 file_type
= s1
->output_type
;
7175 if (file_type
!= TCC_OUTPUT_OBJ
)
7176 tcc_add_runtime(s1
);
7183 plt
= NULL
; /* avoid warning */
7184 dynstr
= NULL
; /* avoid warning */
7185 saved_dynamic_data_offset
= 0; /* avoid warning */
7187 if (file_type
!= TCC_OUTPUT_OBJ
) {
7189 relocate_common_syms();
7193 int sym_index
, index
;
7194 Elf32_Sym
*esym
, *sym_end
;
7196 if (file_type
== TCC_OUTPUT_EXE
) {
7198 /* add interpreter section only if executable */
7199 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
7200 interp
->sh_addralign
= 1;
7201 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
7202 strcpy(ptr
, elf_interp
);
7205 /* add dynamic symbol table */
7206 dynsym
= new_symtab(".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
7208 ".hash", SHF_ALLOC
);
7209 dynstr
= dynsym
->link
;
7211 /* add dynamic section */
7212 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
7213 SHF_ALLOC
| SHF_WRITE
);
7214 dynamic
->link
= dynstr
;
7215 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
7218 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7219 plt
->sh_entsize
= 4;
7223 /* scan for undefined symbols and see if they are in the
7224 dynamic symbols. If a symbol STT_FUNC is found, then we
7225 add it in the PLT. If a symbol STT_OBJECT is found, we
7226 add it in the .bss section with a suitable relocation */
7227 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
7228 symtab_section
->data_offset
);
7229 if (file_type
== TCC_OUTPUT_EXE
) {
7230 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7233 if (sym
->st_shndx
== SHN_UNDEF
) {
7234 name
= symtab_section
->link
->data
+ sym
->st_name
;
7235 sym_index
= find_elf_sym(dynsymtab_section
, name
);
7237 esym
= &((Elf32_Sym
*)dynsymtab_section
->data
)[sym_index
];
7238 type
= ELF32_ST_TYPE(esym
->st_info
);
7239 if (type
== STT_FUNC
) {
7240 put_got_entry(R_386_JMP_SLOT
, esym
->st_size
,
7242 sym
- (Elf32_Sym
*)symtab_section
->data
);
7243 } else if (type
== STT_OBJECT
) {
7244 unsigned long offset
;
7245 offset
= bss_section
->data_offset
;
7246 /* XXX: which alignment ? */
7247 offset
= (offset
+ 8 - 1) & -8;
7248 index
= put_elf_sym(dynsym
, offset
, esym
->st_size
,
7250 bss_section
->sh_num
, name
);
7251 put_elf_reloc(dynsym
, bss_section
,
7252 offset
, R_386_COPY
, index
);
7253 offset
+= esym
->st_size
;
7254 bss_section
->data_offset
= offset
;
7257 /* STB_WEAK undefined symbols are accepted */
7258 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
7260 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
||
7261 !strcmp(name
, "_fp_hw")) {
7263 error("undefined symbol '%s'", name
);
7269 /* now look at unresolved dynamic symbols and export
7270 corresponding symbol */
7271 sym_end
= (Elf32_Sym
*)(dynsymtab_section
->data
+
7272 dynsymtab_section
->data_offset
);
7273 for(esym
= (Elf32_Sym
*)dynsymtab_section
->data
+ 1;
7276 if (esym
->st_shndx
== SHN_UNDEF
) {
7277 name
= dynsymtab_section
->link
->data
+ esym
->st_name
;
7278 sym_index
= find_elf_sym(symtab_section
, name
);
7280 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
7281 put_elf_sym(dynsym
, sym
->st_value
, sym
->st_size
,
7283 sym
->st_shndx
, name
);
7285 if (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) {
7286 /* weak symbols can stay undefined */
7288 warning("undefined dynamic symbol '%s'", name
);
7295 /* shared library case : we simply export all the global symbols */
7296 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
7297 symtab_to_dynsym
= malloc(sizeof(int) * nb_syms
);
7298 memset(symtab_to_dynsym
, 0, sizeof(int) * nb_syms
);
7299 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7302 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
7303 name
= symtab_section
->link
->data
+ sym
->st_name
;
7304 index
= put_elf_sym(dynsym
, sym
->st_value
, sym
->st_size
,
7306 sym
->st_shndx
, name
);
7307 symtab_to_dynsym
[sym
- (Elf32_Sym
*)symtab_section
->data
] =
7313 build_got_entries();
7315 /* update PLT/GOT sizes so that we can allocate their space */
7316 plt
->data_offset
+= 16 * (nb_plt_entries
+ 1);
7318 /* add a list of needed dlls */
7319 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
7320 DLLReference
*dllref
= loaded_dlls
[i
];
7321 if (dllref
->level
== 0)
7322 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
7324 /* XXX: currently, since we do not handle PIC code, we
7325 must relocate the readonly segments */
7326 if (file_type
== TCC_OUTPUT_DLL
)
7327 put_dt(dynamic
, DT_TEXTREL
, 0);
7329 /* add necessary space for other entries */
7330 saved_dynamic_data_offset
= dynamic
->data_offset
;
7331 dynamic
->data_offset
+= 8 * 9;
7333 /* still need to build got entries in case of static link */
7334 build_got_entries();
7338 memset(&ehdr
, 0, sizeof(ehdr
));
7340 /* we add a section for symbols */
7341 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
7342 put_elf_str(strsec
, "");
7344 /* compute number of sections */
7345 shnum
= nb_sections
;
7347 /* this array is used to reorder sections in the output file */
7348 section_order
= malloc(sizeof(int) * shnum
);
7350 error("memory full");
7351 section_order
[0] = 0;
7354 /* compute number of program headers */
7357 case TCC_OUTPUT_OBJ
:
7360 case TCC_OUTPUT_EXE
:
7366 case TCC_OUTPUT_DLL
:
7371 /* allocate strings for section names and decide if an unallocated
7372 section should be output */
7373 /* NOTE: the strsec section comes last, so its size is also
7375 for(i
= 1; i
< nb_sections
; i
++) {
7377 s
->sh_name
= put_elf_str(strsec
, s
->name
);
7378 /* when generating a DLL, we include relocations but we may
7380 if (file_type
== TCC_OUTPUT_DLL
&&
7381 s
->sh_type
== SHT_REL
&&
7382 !(s
->sh_flags
& SHF_ALLOC
)) {
7383 prepare_dynamic_rel(s
);
7384 } else if (do_debug
||
7385 file_type
== TCC_OUTPUT_OBJ
||
7386 (s
->sh_flags
& SHF_ALLOC
) ||
7387 i
== (nb_sections
- 1)) {
7388 /* we output all sections if debug or object file */
7389 s
->sh_size
= s
->data_offset
;
7393 /* allocate program segment headers */
7394 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
7396 error("memory full");
7397 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
7399 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7401 /* compute section to program header mapping */
7402 if (file_type
== TCC_OUTPUT_DLL
)
7405 addr
= ELF_START_ADDR
;
7407 /* dynamic relocation table information, for .dynamic section */
7411 /* compute address after headers */
7412 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
7414 /* leave one program header for the program interpreter */
7419 for(j
= 0; j
< 2; j
++) {
7420 ph
->p_type
= PT_LOAD
;
7422 ph
->p_flags
= PF_R
| PF_X
;
7424 ph
->p_flags
= PF_R
| PF_W
;
7425 ph
->p_align
= ELF_PAGE_SIZE
;
7427 /* we do the following ordering: interp, symbol tables,
7428 relocations, progbits, nobits */
7429 /* XXX: do faster and simpler sorting */
7430 for(k
= 0; k
< 5; k
++) {
7431 for(i
= 1; i
< nb_sections
; i
++) {
7433 /* compute if section should be included */
7435 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7439 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
7440 (SHF_ALLOC
| SHF_WRITE
))
7446 } else if (s
->sh_type
== SHT_DYNSYM
||
7447 s
->sh_type
== SHT_STRTAB
||
7448 s
->sh_type
== SHT_HASH
) {
7451 } else if (s
->sh_type
== SHT_REL
) {
7454 } else if (s
->sh_type
== SHT_NOBITS
) {
7461 section_order
[sh_order_index
++] = i
;
7463 /* section matches: we align it and add its size */
7465 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7466 ~(s
->sh_addralign
- 1);
7467 s
->sh_offset
= file_offset
;
7468 addr
+= file_offset
- tmp
;
7471 /* update program header infos */
7472 if (ph
->p_offset
== 0) {
7473 ph
->p_offset
= file_offset
;
7475 ph
->p_paddr
= ph
->p_vaddr
;
7477 /* update dynamic relocation infos */
7478 if (s
->sh_type
== SHT_REL
) {
7481 rel_size
+= s
->sh_size
;
7484 if (s
->sh_type
!= SHT_NOBITS
)
7485 file_offset
+= s
->sh_size
;
7488 ph
->p_filesz
= file_offset
- ph
->p_offset
;
7489 ph
->p_memsz
= addr
- ph
->p_vaddr
;
7493 /* if interpreter, then add corresponing program header */
7497 ph
->p_type
= PT_INTERP
;
7498 ph
->p_offset
= interp
->sh_offset
;
7499 ph
->p_vaddr
= interp
->sh_addr
;
7500 ph
->p_paddr
= ph
->p_vaddr
;
7501 ph
->p_filesz
= interp
->sh_size
;
7502 ph
->p_memsz
= interp
->sh_size
;
7504 ph
->p_align
= interp
->sh_addralign
;
7507 /* if dynamic section, then add corresponing program header */
7513 ph
= &phdr
[phnum
- 1];
7515 ph
->p_type
= PT_DYNAMIC
;
7516 ph
->p_offset
= dynamic
->sh_offset
;
7517 ph
->p_vaddr
= dynamic
->sh_addr
;
7518 ph
->p_paddr
= ph
->p_vaddr
;
7519 ph
->p_filesz
= dynamic
->sh_size
;
7520 ph
->p_memsz
= dynamic
->sh_size
;
7521 ph
->p_flags
= PF_R
| PF_W
;
7522 ph
->p_align
= dynamic
->sh_addralign
;
7524 /* put GOT dynamic section address */
7525 put32(got
->data
, dynamic
->sh_addr
);
7527 /* compute the PLT */
7528 plt
->data_offset
= 0;
7530 /* first plt entry */
7531 p
= section_ptr_add(plt
, 16);
7532 p
[0] = 0xff; /* pushl got + 4 */
7534 put32(p
+ 2, got
->sh_addr
+ 4);
7535 p
[6] = 0xff; /* jmp *(got + 8) */
7537 put32(p
+ 8, got
->sh_addr
+ 8);
7539 /* relocation symbols in .dynsym and build PLT. */
7541 sym_end
= (Elf32_Sym
*)(dynsym
->data
+ dynsym
->data_offset
);
7542 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
7545 type
= ELF32_ST_TYPE(sym
->st_info
);
7546 if (sym
->st_shndx
== SHN_UNDEF
) {
7547 if (type
== STT_FUNC
) {
7548 /* one more entry in PLT */
7549 p
= section_ptr_add(plt
, 16);
7550 p
[0] = 0xff; /* jmp *(got + x) */
7552 put32(p
+ 2, got
->sh_addr
+ sym
->st_value
);
7553 p
[6] = 0x68; /* push $xxx */
7554 put32(p
+ 7, plt_offset
);
7555 p
[11] = 0xe9; /* jmp plt_start */
7556 put32(p
+ 12, -(plt
->data_offset
));
7558 /* patch symbol value to point to plt */
7559 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
7563 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
7564 /* do symbol relocation */
7565 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
7568 /* put dynamic section entries */
7570 dynamic
->data_offset
= saved_dynamic_data_offset
;
7571 put_dt(dynamic
, DT_HASH
, dynsym
->hash
->sh_addr
);
7572 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
7573 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
7574 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
7575 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
7576 put_dt(dynamic
, DT_REL
, rel_addr
);
7577 put_dt(dynamic
, DT_RELSZ
, rel_size
);
7578 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
7579 put_dt(dynamic
, DT_NULL
, 0);
7582 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
7583 ehdr
.e_phnum
= phnum
;
7584 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
7587 /* all other sections come after */
7588 for(i
= 1; i
< nb_sections
; i
++) {
7590 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
7592 section_order
[sh_order_index
++] = i
;
7594 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
7595 ~(s
->sh_addralign
- 1);
7596 s
->sh_offset
= file_offset
;
7597 if (s
->sh_type
!= SHT_NOBITS
)
7598 file_offset
+= s
->sh_size
;
7601 /* if building executable or DLL, then relocate each section
7602 except the GOT which is already relocated */
7603 if (file_type
!= TCC_OUTPUT_OBJ
) {
7606 /* relocate sections */
7607 /* XXX: ignore sections with allocated relocations ? */
7608 for(i
= 1; i
< nb_sections
; i
++) {
7610 if (s
->reloc
&& s
!= got
)
7611 relocate_section(s1
, s
);
7614 /* relocate relocation entries if the relocation tables are
7615 allocated in the executable */
7616 for(i
= 1; i
< nb_sections
; i
++) {
7618 if ((s
->sh_flags
& SHF_ALLOC
) &&
7619 s
->sh_type
== SHT_REL
) {
7624 /* get entry point address */
7625 if (file_type
== TCC_OUTPUT_EXE
)
7626 ehdr
.e_entry
= get_elf_sym_val("_start");
7628 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
7631 sort_syms(symtab_section
);
7634 file_offset
= (file_offset
+ 3) & -4;
7637 ehdr
.e_ident
[0] = ELFMAG0
;
7638 ehdr
.e_ident
[1] = ELFMAG1
;
7639 ehdr
.e_ident
[2] = ELFMAG2
;
7640 ehdr
.e_ident
[3] = ELFMAG3
;
7641 ehdr
.e_ident
[4] = ELFCLASS32
;
7642 ehdr
.e_ident
[5] = ELFDATA2LSB
;
7643 ehdr
.e_ident
[6] = EV_CURRENT
;
7646 case TCC_OUTPUT_EXE
:
7647 ehdr
.e_type
= ET_EXEC
;
7649 case TCC_OUTPUT_DLL
:
7650 ehdr
.e_type
= ET_DYN
;
7652 case TCC_OUTPUT_OBJ
:
7653 ehdr
.e_type
= ET_REL
;
7656 ehdr
.e_machine
= EM_386
;
7657 ehdr
.e_version
= EV_CURRENT
;
7658 ehdr
.e_shoff
= file_offset
;
7659 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
7660 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
7661 ehdr
.e_shnum
= shnum
;
7662 ehdr
.e_shstrndx
= shnum
- 1;
7664 /* write elf file */
7665 if (file_type
== TCC_OUTPUT_OBJ
)
7669 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
7671 error("could not write '%s'", filename
);
7673 f
= fdopen(fd
, "w");
7674 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
7675 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
7676 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
7677 for(i
=1;i
<nb_sections
;i
++) {
7678 s
= sections
[section_order
[i
]];
7679 if (s
->sh_type
!= SHT_NOBITS
) {
7680 while (offset
< s
->sh_offset
) {
7685 fwrite(s
->data
, 1, size
, f
);
7689 while (offset
< ehdr
.e_shoff
) {
7694 /* output section headers */
7695 for(i
=0;i
<nb_sections
;i
++) {
7697 memset(sh
, 0, sizeof(Elf32_Shdr
));
7700 sh
->sh_name
= s
->sh_name
;
7701 sh
->sh_type
= s
->sh_type
;
7702 sh
->sh_flags
= s
->sh_flags
;
7703 sh
->sh_entsize
= s
->sh_entsize
;
7704 sh
->sh_info
= s
->sh_info
;
7706 sh
->sh_link
= s
->link
->sh_num
;
7707 sh
->sh_addralign
= s
->sh_addralign
;
7708 sh
->sh_addr
= s
->sh_addr
;
7709 sh
->sh_offset
= s
->sh_offset
;
7710 sh
->sh_size
= s
->sh_size
;
7712 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
7716 free(section_order
);
7721 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
7725 data
= malloc(size
);
7727 error("memory full");
7728 lseek(fd
, file_offset
, SEEK_SET
);
7729 read(fd
, data
, size
);
7733 typedef struct SectionMergeInfo
{
7734 Section
*s
; /* corresponding existing section */
7735 unsigned long offset
; /* offset of the new section in the existing section */
7736 int new_section
; /* true if section 's' was added */
7739 /* load an object file and merge it with current files */
7740 /* XXX: handle correctly stab (debug) info */
7741 static int tcc_load_object_file(TCCState
*s1
,
7742 int fd
, unsigned long file_offset
)
7745 Elf32_Shdr
*shdr
, *sh
;
7746 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
;
7747 unsigned char *strsec
, *strtab
;
7748 int *old_to_new_syms
;
7749 char *sh_name
, *name
;
7750 SectionMergeInfo
*sm_table
, *sm
;
7751 Elf32_Sym
*sym
, *symtab
;
7752 Elf32_Rel
*rel
, *rel_end
;
7755 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
7757 if (ehdr
.e_ident
[0] != ELFMAG0
||
7758 ehdr
.e_ident
[1] != ELFMAG1
||
7759 ehdr
.e_ident
[2] != ELFMAG2
||
7760 ehdr
.e_ident
[3] != ELFMAG3
)
7762 /* test if object file */
7763 if (ehdr
.e_type
!= ET_REL
)
7765 /* test CPU specific stuff */
7766 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
7767 ehdr
.e_machine
!= EM_386
) {
7769 error("invalid object file");
7772 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
7773 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
7774 sm_table
= malloc(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7776 error("memory full");
7777 memset(sm_table
, 0, sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
7779 /* load section names */
7780 sh
= &shdr
[ehdr
.e_shstrndx
];
7781 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7783 /* load symtab and strtab */
7787 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7789 if (sh
->sh_type
== SHT_SYMTAB
) {
7791 error("object must contain only one symtab");
7792 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
7793 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7794 sm_table
[i
].s
= symtab_section
;
7796 /* now load strtab */
7797 sh
= &shdr
[sh
->sh_link
];
7798 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
7802 /* now examine each section and try to merge its content with the
7804 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7805 /* no need to examine section name strtab */
7806 if (i
== ehdr
.e_shstrndx
)
7809 sh_name
= strsec
+ sh
->sh_name
;
7810 /* ignore sections types we do not handle */
7811 if (sh
->sh_type
!= SHT_PROGBITS
&&
7812 sh
->sh_type
!= SHT_REL
&&
7813 sh
->sh_type
!= SHT_NOBITS
)
7815 if (sh
->sh_addralign
< 1)
7816 sh
->sh_addralign
= 1;
7817 /* find corresponding section, if any */
7818 for(j
= 1; j
< nb_sections
;j
++) {
7820 if (!strcmp(s
->name
, sh_name
))
7823 /* not found: create new section */
7824 s
= new_section(sh_name
, sh
->sh_type
, sh
->sh_flags
);
7825 /* take as much info as possible from the section. sh_link and
7826 sh_info will be updated later */
7827 s
->sh_addralign
= sh
->sh_addralign
;
7828 s
->sh_entsize
= sh
->sh_entsize
;
7829 sm_table
[i
].new_section
= 1;
7831 if (sh
->sh_type
!= s
->sh_type
)
7834 /* align start of section */
7835 offset
= s
->data_offset
;
7836 size
= sh
->sh_addralign
- 1;
7837 offset
= (offset
+ size
) & ~size
;
7838 if (sh
->sh_addralign
> s
->sh_addralign
)
7839 s
->sh_addralign
= sh
->sh_addralign
;
7840 s
->data_offset
= offset
;
7841 sm_table
[i
].offset
= offset
;
7843 /* concatenate sections */
7845 if (sh
->sh_type
!= SHT_NOBITS
) {
7847 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
7848 ptr
= section_ptr(s
, size
);
7849 read(fd
, ptr
, size
);
7851 s
->data_offset
+= size
;
7854 /* second short pass to update sh_link and sh_info fields of new
7857 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7859 if (!s
|| !sm_table
[i
].new_section
)
7862 if (sh
->sh_link
> 0)
7863 s
->link
= sm_table
[sh
->sh_link
].s
;
7864 if (sh
->sh_type
== SHT_REL
) {
7865 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
7866 /* update backward link */
7867 sections
[s
->sh_info
]->reloc
= s
;
7871 /* resolve symbols */
7872 old_to_new_syms
= malloc(nb_syms
* sizeof(int));
7873 if (!old_to_new_syms
)
7874 error("memory full");
7875 memset(old_to_new_syms
, 0, nb_syms
* sizeof(int));
7877 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
7878 if (sym
->st_shndx
!= SHN_UNDEF
&&
7879 sym
->st_shndx
< SHN_LORESERVE
) {
7880 sm
= &sm_table
[sym
->st_shndx
];
7881 /* if no corresponding section added, no need to add symbol */
7884 /* convert section number */
7885 sym
->st_shndx
= sm
->s
->sh_num
;
7887 sym
->st_value
+= sm
->offset
;
7890 name
= strtab
+ sym
->st_name
;
7891 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
7892 sym
->st_info
, sym
->st_shndx
, name
);
7893 old_to_new_syms
[i
] = sym_index
;
7896 /* third pass to patch relocation entries */
7897 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
7902 offset
= sm_table
[i
].offset
;
7903 switch(s
->sh_type
) {
7905 /* take relocation offset information */
7906 offseti
= sm_table
[sh
->sh_info
].offset
;
7907 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
7908 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
7913 /* convert symbol index */
7914 type
= ELF32_R_TYPE(rel
->r_info
);
7915 sym_index
= ELF32_R_SYM(rel
->r_info
);
7916 /* NOTE: only one symtab assumed */
7917 if (sym_index
>= nb_syms
)
7919 sym_index
= old_to_new_syms
[sym_index
];
7922 error("Invalid relocation entry");
7924 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
7925 /* offset the relocation offset */
7926 rel
->r_offset
+= offseti
;
7935 free(old_to_new_syms
);
7941 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
7943 typedef struct ArchiveHeader
{
7944 char ar_name
[16]; /* name of this member */
7945 char ar_date
[12]; /* file mtime */
7946 char ar_uid
[6]; /* owner uid; printed as decimal */
7947 char ar_gid
[6]; /* owner gid; printed as decimal */
7948 char ar_mode
[8]; /* file mode, printed as octal */
7949 char ar_size
[10]; /* file size, printed as decimal */
7950 char ar_fmag
[2]; /* should contain ARFMAG */
7953 /* load a '.a' file */
7954 static int tcc_load_archive(TCCState
*s1
, int fd
)
7961 unsigned long file_offset
;
7963 /* skip magic which was already checked */
7964 read(fd
, magic
, sizeof(magic
));
7967 len
= read(fd
, &hdr
, sizeof(hdr
));
7970 if (len
!= sizeof(hdr
))
7971 error("invalid archive");
7972 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
7973 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
7974 size
= strtol(ar_size
, NULL
, 0);
7975 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
7976 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
7977 if (ar_name
[i
] != ' ')
7980 ar_name
[i
+ 1] = '\0';
7981 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
7982 file_offset
= lseek(fd
, 0, SEEK_CUR
);
7983 if (!strcmp(ar_name
, "/") ||
7984 !strcmp(ar_name
, "//") ||
7985 !strcmp(ar_name
, "__.SYMDEF") ||
7986 !strcmp(ar_name
, "__.SYMDEF/") ||
7987 !strcmp(ar_name
, "ARFILENAMES/")) {
7988 /* skip symbol table or archive names */
7990 tcc_load_object_file(s1
, fd
, file_offset
);
7993 size
= (size
+ 1) & ~1;
7994 lseek(fd
, file_offset
+ size
, SEEK_SET
);
7999 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
8000 is referenced by the user (so it should be added as DT_NEEDED in
8001 the generated ELF file) */
8002 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
8005 Elf32_Shdr
*shdr
, *sh
, *sh1
;
8006 int i
, nb_syms
, nb_dts
, sym_bind
;
8007 Elf32_Sym
*sym
, *dynsym
;
8008 Elf32_Dyn
*dt
, *dynamic
;
8009 unsigned char *dynstr
;
8010 const char *name
, *soname
, *p
;
8011 DLLReference
*dllref
;
8013 read(fd
, &ehdr
, sizeof(ehdr
));
8015 /* test CPU specific stuff */
8016 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
8017 ehdr
.e_machine
!= EM_386
)
8018 error("bad architecture");
8021 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
8023 /* load dynamic section and dynamic symbols */
8027 dynsym
= NULL
; /* avoid warning */
8028 dynstr
= NULL
; /* avoid warning */
8029 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
8030 switch(sh
->sh_type
) {
8032 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
8033 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
8036 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
8037 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
8038 sh1
= &shdr
[sh
->sh_link
];
8039 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
8046 /* compute the real library name */
8048 p
= strrchr(soname
, '/');
8052 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
8053 if (dt
->d_tag
== DT_SONAME
) {
8054 soname
= dynstr
+ dt
->d_un
.d_val
;
8058 /* if the dll is already loaded, do not load it */
8059 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
8060 dllref
= loaded_dlls
[i
];
8061 if (!strcmp(soname
, dllref
->name
)) {
8062 /* but update level if needed */
8063 if (level
< dllref
->level
)
8064 dllref
->level
= level
;
8069 // printf("loading dll '%s'\n", soname);
8071 /* add the dll and its level */
8072 dllref
= malloc(sizeof(DLLReference
) + strlen(soname
));
8073 dllref
->level
= level
;
8074 strcpy(dllref
->name
, soname
);
8075 dynarray_add((void ***)&loaded_dlls
, &nb_loaded_dlls
, dllref
);
8077 /* add dynamic symbols in dynsym_section */
8078 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
8079 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
8080 if (sym_bind
== STB_LOCAL
)
8082 name
= dynstr
+ sym
->st_name
;
8083 add_elf_sym(dynsymtab_section
, sym
->st_value
, sym
->st_size
,
8084 sym
->st_info
, sym
->st_shndx
, name
);
8087 /* load all referenced DLLs */
8088 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
8091 name
= dynstr
+ dt
->d_un
.d_val
;
8092 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
8093 dllref
= loaded_dlls
[i
];
8094 if (!strcmp(name
, dllref
->name
))
8095 goto already_loaded
;
8097 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0)
8098 error("referenced dll '%s' not found", name
);
8108 /* return -2 if error and CH_EOF if eof */
8109 static void ld_skipspaces(void)
8111 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
8115 static int ld_get_cmd(char *cmd
, int cmd_size
)
8124 if (!((ch
>= 'a' && ch
<= 'z') ||
8125 (ch
>= 'A' && ch
<= 'Z') ||
8126 (ch
>= '0' && ch
<= '9') ||
8127 strchr("/.-_+=$:\\,~?*", ch
)))
8129 if ((q
- cmd
) >= (cmd_size
- 1))
8138 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
8140 static int tcc_load_ldscript(TCCState
*s1
)
8143 char filename
[1024];
8149 ret
= ld_get_cmd(cmd
, sizeof(cmd
));
8154 // printf("cmd='%s'\n", cmd);
8155 if (!strcmp(cmd
, "INPUT") ||
8156 !strcmp(cmd
, "GROUP")) {
8162 ld_get_cmd(filename
, sizeof(filename
));
8163 tcc_add_file(s1
, filename
);
8167 } else if (ch
== ')') {
8170 } else if (ch
== CH_EOF
) {
8171 error("unexpected end of file");
8181 /* print the position in the source file of PC value 'pc' by reading
8182 the stabs debug information */
8183 static void rt_printline(unsigned long wanted_pc
)
8185 Stab_Sym
*sym
, *sym_end
;
8186 char func_name
[128];
8187 unsigned long func_addr
, last_pc
, pc
;
8188 const char *incl_files
[INCLUDE_STACK_SIZE
];
8189 int incl_index
, len
, last_line_num
, i
;
8190 const char *str
, *p
;
8192 func_name
[0] = '\0';
8195 last_pc
= 0xffffffff;
8197 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
8198 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
8199 while (sym
< sym_end
) {
8200 switch(sym
->n_type
) {
8201 /* function start or end */
8203 if (sym
->n_strx
== 0) {
8204 func_name
[0] = '\0';
8207 str
= stabstr_section
->data
+ sym
->n_strx
;
8208 p
= strchr(str
, ':');
8210 pstrcpy(func_name
, sizeof(func_name
), str
);
8213 if (len
> sizeof(func_name
) - 1)
8214 len
= sizeof(func_name
) - 1;
8215 memcpy(func_name
, str
, len
);
8216 func_name
[len
] = '\0';
8218 func_addr
= sym
->n_value
;
8221 /* line number info */
8223 pc
= sym
->n_value
+ func_addr
;
8224 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8227 last_line_num
= sym
->n_desc
;
8231 str
= stabstr_section
->data
+ sym
->n_strx
;
8233 if (incl_index
< INCLUDE_STACK_SIZE
) {
8234 incl_files
[incl_index
++] = str
;
8242 if (sym
->n_strx
== 0) {
8243 incl_index
= 0; /* end of translation unit */
8245 str
= stabstr_section
->data
+ sym
->n_strx
;
8246 /* do not add path */
8248 if (len
> 0 && str
[len
- 1] != '/')
8255 /* did not find line number info: */
8256 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
8259 for(i
= 0; i
< incl_index
- 1; i
++)
8260 fprintf(stderr
, "In file included from %s\n",
8262 if (incl_index
> 0) {
8263 fprintf(stderr
, "%s:%d: ",
8264 incl_files
[incl_index
- 1], last_line_num
);
8266 if (func_name
[0] != '\0') {
8267 fprintf(stderr
, "in function '%s()': ", func_name
);
8271 /* emit a run time error at position 'pc' */
8272 void rt_error(unsigned long pc
, const char *fmt
, ...)
8278 vfprintf(stderr
, fmt
, ap
);
8279 fprintf(stderr
, "\n");
8285 /* signal handler for fatal errors */
8286 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
8288 struct ucontext
*uc
= puc
;
8292 pc
= uc
->uc_mcontext
.gregs
[14];
8294 #error please put the right sigcontext field
8299 switch(siginf
->si_code
) {
8302 rt_error(pc
, "division by zero");
8305 rt_error(pc
, "floating point exception");
8311 rt_error(pc
, "dereferencing invalid pointer");
8314 rt_error(pc
, "illegal instruction");
8317 rt_error(pc
, "abort() called");
8320 rt_error(pc
, "caught signal %d", signum
);
8327 /* launch the compiled program with the given arguments */
8328 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8331 int (*prog_main
)(int, char **);
8332 void (*bound_init
)(void);
8335 tcc_add_runtime(s1
);
8337 relocate_common_syms();
8339 /* compute relocation address : section are relocated in place */
8340 for(i
= 1; i
< nb_sections
; i
++) {
8342 if (s
->sh_flags
& SHF_ALLOC
)
8343 s
->sh_addr
= (unsigned long)s
->data
;
8348 /* relocate each section */
8349 for(i
= 1; i
< nb_sections
; i
++) {
8352 relocate_section(s1
, s
);
8355 prog_main
= (void *)get_elf_sym_val("main");
8359 error("debug mode currently not available for Windows");
8361 struct sigaction sigact
;
8362 /* install TCC signal handlers to print debug info on fatal
8364 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8365 sigact
.sa_sigaction
= sig_error
;
8366 sigemptyset(&sigact
.sa_mask
);
8367 sigaction(SIGFPE
, &sigact
, NULL
);
8368 sigaction(SIGILL
, &sigact
, NULL
);
8369 sigaction(SIGSEGV
, &sigact
, NULL
);
8370 sigaction(SIGBUS
, &sigact
, NULL
);
8371 sigaction(SIGABRT
, &sigact
, NULL
);
8375 #ifdef CONFIG_TCC_BCHECK
8376 if (do_bounds_check
) {
8377 /* XXX: use .init section so that it also work in binary ? */
8378 bound_init
= (void *)get_elf_sym_val("__bound_init");
8382 return (*prog_main
)(argc
, argv
);
8385 TCCState
*tcc_new(void)
8390 s
= malloc(sizeof(TCCState
));
8393 s
->output_type
= TCC_OUTPUT_MEMORY
;
8395 /* default include paths */
8396 tcc_add_include_path(s
, "/usr/include");
8397 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8398 tcc_add_include_path(s
, "/usr/local/include");
8400 /* add all tokens */
8401 tok_ident
= TOK_IDENT
;
8406 tok_alloc(p
, r
- p
- 1);
8410 /* standard defines */
8411 tcc_define_symbol(s
, "__STDC__", NULL
);
8412 #if defined(TCC_TARGET_I386)
8413 tcc_define_symbol(s
, "__i386__", NULL
);
8415 /* tiny C specific defines */
8416 tcc_define_symbol(s
, "__TINYC__", NULL
);
8418 /* default library paths */
8419 tcc_add_library_path(s
, "/usr/local/lib");
8420 tcc_add_library_path(s
, "/usr/lib");
8421 tcc_add_library_path(s
, "/lib");
8423 /* no section zero */
8424 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
8426 /* create standard sections */
8427 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8428 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8429 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8431 /* symbols are always generated for linking stage */
8432 symtab_section
= new_symtab(".symtab", SHT_SYMTAB
, 0,
8434 ".hashtab", SHF_PRIVATE
);
8435 strtab_section
= symtab_section
->link
;
8437 /* private symbol table for dynamic symbols */
8438 dynsymtab_section
= new_symtab(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
8440 ".dynhashtab", SHF_PRIVATE
);
8444 void tcc_delete(TCCState
*s
)
8449 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
8453 pathname1
= strdup(pathname
);
8456 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
8460 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
8465 BufferedFile
*saved_file
;
8467 /* find source file type with extension */
8468 ext
= strrchr(filename
, '.');
8474 file
= tcc_open(filename
);
8476 if (flags
& AFF_PRINT_ERROR
) {
8477 error("file '%s' not found", filename
);
8484 if (!ext
|| !strcmp(ext
, "c")) {
8485 /* C file assumed */
8489 /* assume executable format: auto guess file type */
8490 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
8491 error("could not read header");
8492 lseek(fd
, 0, SEEK_SET
);
8494 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8495 ehdr
.e_ident
[1] == ELFMAG1
&&
8496 ehdr
.e_ident
[2] == ELFMAG2
&&
8497 ehdr
.e_ident
[3] == ELFMAG3
) {
8498 file
->line_num
= 0; /* do not display line number if error */
8499 if (ehdr
.e_type
== ET_REL
) {
8500 tcc_load_object_file(s
, fd
, 0);
8501 } else if (ehdr
.e_type
== ET_DYN
) {
8502 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
8504 error("unrecognized ELF file");
8506 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8507 file
->line_num
= 0; /* do not display line number if error */
8508 tcc_load_archive(s
, fd
);
8510 /* as GNU ld, consider it is an ld script if not recognized */
8511 if (tcc_load_ldscript(s
) < 0)
8512 error("unrecognized file type");
8520 void tcc_add_file(TCCState
*s
, const char *filename
)
8522 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8525 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8529 pathname1
= strdup(pathname
);
8532 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
8536 /* find and load a dll. Return non zero if not found */
8537 /* XXX: add '-rpath' option support ? */
8538 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8543 for(i
= 0; i
< nb_library_paths
; i
++) {
8544 snprintf(buf
, sizeof(buf
), "%s/%s",
8545 library_paths
[i
], filename
);
8546 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8552 /* the library name is the same as the argument of the '-l' option */
8553 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8559 /* if we output to memory, then we simply we dlopen(). */
8560 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8561 /* Since the libc is already loaded, we don't need to load it again */
8562 if (!strcmp(libraryname
, "c"))
8564 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8565 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8571 /* first we look for the dynamic library if not static linking */
8573 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8574 if (tcc_add_dll(s
, buf
, 0) == 0)
8578 /* then we look for the static library */
8579 for(i
= 0; i
< nb_library_paths
; i
++) {
8580 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8581 library_paths
[i
], libraryname
);
8582 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8588 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8590 add_elf_sym(symtab_section
, val
, 0,
8591 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8596 int tcc_set_output_type(TCCState
*s
, int output_type
)
8598 s
->output_type
= output_type
;
8600 /* if bound checking, then add corresponding sections */
8601 #ifdef CONFIG_TCC_BCHECK
8602 if (do_bounds_check
) {
8604 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8605 /* create bounds sections */
8606 bounds_section
= new_section(".bounds",
8607 SHT_PROGBITS
, SHF_ALLOC
);
8608 lbounds_section
= new_section(".lbounds",
8609 SHT_PROGBITS
, SHF_ALLOC
);
8613 /* add debug sections */
8616 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
8617 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8618 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
8619 put_elf_str(stabstr_section
, "");
8620 stab_section
->link
= stabstr_section
;
8621 /* put first entry */
8622 put_stabs("", 0, 0, 0, 0);
8625 /* add libc crt1/crti objects */
8626 if (output_type
== TCC_OUTPUT_EXE
||
8627 output_type
== TCC_OUTPUT_DLL
) {
8628 if (output_type
!= TCC_OUTPUT_DLL
)
8629 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8630 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8635 #if !defined(LIBTCC)
8639 printf("tcc version 0.9.9 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8640 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8641 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
8642 " [--] infile1 [infile2... --] [infile_args...]\n"
8644 "General options:\n"
8645 " -c compile only - generate an object file\n"
8646 " -o outfile set output filename\n"
8647 " -- allows multiples input files if no -o option given. Also\n"
8648 " separate input files from runtime arguments\n"
8649 " -Bdir set tcc internal library path\n"
8650 " -bench output compilation statistics\n"
8651 "Preprocessor options:\n"
8652 " -Idir add include path 'dir'\n"
8653 " -Dsym[=val] define 'sym' with value 'val'\n"
8654 " -Usym undefine 'sym'\n"
8655 "C compiler options:\n"
8656 " -g generate runtime debug info\n"
8657 #ifdef CONFIG_TCC_BCHECK
8658 " -b compile with built-in memory and bounds checker (implies -g)\n"
8661 " -Ldir add library path 'dir'\n"
8662 " -llib link with dynamic library 'lib'\n"
8663 " -shared generate a shared library\n"
8664 " -static static linking\n"
8668 int main(int argc
, char **argv
)
8671 int optind
, output_type
, multiple_files
, i
;
8677 output_type
= TCC_OUTPUT_MEMORY
;
8685 if (optind
>= argc
) {
8695 /* '--' enables multiple files input */
8697 } else if (r
[1] == 'h' || r
[1] == '?') {
8699 } else if (r
[1] == 'I') {
8700 if (tcc_add_include_path(s
, r
+ 2) < 0)
8701 error("too many include paths");
8702 } else if (r
[1] == 'D') {
8705 value
= strchr(sym
, '=');
8710 tcc_define_symbol(s
, sym
, value
);
8711 } else if (r
[1] == 'U') {
8712 tcc_undefine_symbol(s
, r
+ 2);
8713 } else if (r
[1] == 'L') {
8714 tcc_add_library_path(s
, r
+ 2);
8715 } else if (r
[1] == 'B') {
8716 /* set tcc utilities path (mainly for tcc development) */
8717 tcc_lib_path
= r
+ 2;
8718 } else if (r
[1] == 'l') {
8719 dynarray_add((void ***)&libraries
, &nb_libraries
, r
+ 2);
8720 } else if (!strcmp(r
+ 1, "bench")) {
8723 #ifdef CONFIG_TCC_BCHECK
8725 do_bounds_check
= 1;
8731 } else if (r
[1] == 'c') {
8733 output_type
= TCC_OUTPUT_OBJ
;
8734 } else if (!strcmp(r
+ 1, "static")) {
8736 } else if (!strcmp(r
+ 1, "shared")) {
8737 output_type
= TCC_OUTPUT_DLL
;
8738 } else if (r
[1] == 'o') {
8742 outfile
= argv
[optind
++];
8744 error("invalid option -- '%s'", r
);
8748 /* if outfile provided without other options, we output an
8750 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8751 output_type
= TCC_OUTPUT_EXE
;
8753 /* warning if not supported features */
8754 #ifdef CONFIG_TCC_BCHECK
8755 if (do_bounds_check
&& output_type
!= TCC_OUTPUT_MEMORY
)
8756 warning("bounds checking is currently only supported for in-memory execution");
8759 tcc_set_output_type(s
, output_type
);
8761 tcc_add_file(s
, argv
[optind
]);
8762 if (multiple_files
) {
8763 while ((optind
+ 1) < argc
) {
8768 error("'--' expected");
8775 /* add specified libraries */
8776 for(i
= 0; i
< nb_libraries
;i
++) {
8777 if (tcc_add_library(s
, libraries
[i
]) < 0)
8778 error("cannot find -l%s", libraries
[i
]);
8782 printf("total: %d idents, %d lines, %d bytes\n",
8783 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
8786 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8787 tcc_output_file(s
, outfile
);
8790 return tcc_run(s
, argc
- optind
, argv
+ optind
);