aboutsummaryrefslogtreecommitdiff
path: root/tcc.h
diff options
context:
space:
mode:
authorjiang <30155751@qq.com>2014-04-29 16:05:16 +0800
committerjiang <30155751@qq.com>2014-04-29 16:05:16 +0800
commit2a8905c93b4f67a21e3dbf297c3e93c598831528 (patch)
tree6f7491150cfe01700c9863946906203adad0de13 /tcc.h
parent02e2fe3c260415f4cb1cbcaca9b2403a17f7ff2e (diff)
parente20c1eb99e1003c1e59522c136dbb15c52d7cc7c (diff)
downloadtinycc-2a8905c93b4f67a21e3dbf297c3e93c598831528.tar.gz
tinycc-2a8905c93b4f67a21e3dbf297c3e93c598831528.tar.bz2
So that the generated code, and more short
Diffstat (limited to 'tcc.h')
-rw-r--r--tcc.h252
1 files changed, 140 insertions, 112 deletions
diff --git a/tcc.h b/tcc.h
index 859d4fd..c93cedf 100644
--- a/tcc.h
+++ b/tcc.h
@@ -55,18 +55,27 @@
# ifndef CONFIG_TCC_STATIC
# include <dlfcn.h>
# endif
-#else
+/* XXX: need to define this to use them in non ISOC99 context */
+ extern float strtof (const char *__nptr, char **__endptr);
+ extern long double strtold (const char *__nptr, char **__endptr);
+#else /* on _WIN32: */
# include <windows.h>
# include <sys/timeb.h>
# include <io.h> /* open, close etc. */
# include <direct.h> /* getcwd */
# ifdef __GNUC__
# include <stdint.h>
-# else
- typedef UINT_PTR uintptr_t;
# endif
# define inline __inline
# define inp next_inp
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+# ifndef __GNUC__
+# define strtold (long double)strtod
+# define strtof (float)strtod
+# define strtoll _strtoi64
+# define strtoull _strtoui64
+# endif
# ifdef LIBTCC_AS_DLL
# define LIBTCCAPI __declspec(dllexport)
# define PUB_FUNC LIBTCCAPI
@@ -79,6 +88,30 @@
# define O_BINARY 0
#endif
+#ifdef __GNUC__
+# define NORETURN __attribute__ ((noreturn))
+#elif defined _MSC_VER
+# define NORETURN __declspec(noreturn)
+#else
+# define NORETURN
+#endif
+
+#ifdef _WIN32
+# define IS_DIRSEP(c) (c == '/' || c == '\\')
+# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
+# define PATHCMP stricmp
+#else
+# define IS_DIRSEP(c) (c == '/')
+# define IS_ABSPATH(p) IS_DIRSEP(p[0])
+# define PATHCMP strcmp
+#endif
+
+#ifdef TCC_TARGET_PE
+#define PATHSEP ';'
+#else
+#define PATHSEP ':'
+#endif
+
#include "elf.h"
#ifdef TCC_TARGET_X86_64
# define ELFCLASSW ELFCLASS64
@@ -128,7 +161,8 @@
#endif
#if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
- !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
+ !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) && \
+ !defined(CONFIG_USE_LIBGCC)
#define CONFIG_TCC_BCHECK /* enable bound checking code */
#endif
@@ -169,9 +203,17 @@
# define CONFIG_LDDIR "lib"
#endif
+#ifdef CONFIG_MULTIARCHDIR
+# define USE_MUADIR(s) s "/" CONFIG_MULTIARCHDIR
+# define ALSO_MUADIR(s) s "/" CONFIG_MULTIARCHDIR ":" s
+#else
+# define USE_MUADIR(s) s
+# define ALSO_MUADIR(s) s
+#endif
+
/* path to find crt1.o, crti.o and crtn.o */
#ifndef CONFIG_TCC_CRTPREFIX
-# define CONFIG_TCC_CRTPREFIX CONFIG_SYSROOT "/usr/" CONFIG_LDDIR
+# define CONFIG_TCC_CRTPREFIX USE_MUADIR(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
#endif
/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */
@@ -180,17 +222,10 @@
#ifndef CONFIG_TCC_SYSINCLUDEPATHS
# ifdef TCC_TARGET_PE
# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include;{B}/include/winapi"
-# elif defined CONFIG_MULTIARCHDIR
-# define CONFIG_TCC_SYSINCLUDEPATHS \
- CONFIG_SYSROOT "/usr/local/include" \
- ":" CONFIG_SYSROOT "/usr/local/include/" CONFIG_MULTIARCHDIR \
- ":" CONFIG_SYSROOT "/usr/include" \
- ":" CONFIG_SYSROOT "/usr/include/" CONFIG_MULTIARCHDIR \
- ":" "{B}/include"
# else
# define CONFIG_TCC_SYSINCLUDEPATHS \
- CONFIG_SYSROOT "/usr/local/include" \
- ":" CONFIG_SYSROOT "/usr/include" \
+ ALSO_MUADIR(CONFIG_SYSROOT "/usr/local/include") \
+ ":" ALSO_MUADIR(CONFIG_SYSROOT "/usr/include") \
":" "{B}/include"
# endif
#endif
@@ -198,12 +233,12 @@
/* library search paths */
#ifndef CONFIG_TCC_LIBPATHS
# ifdef TCC_TARGET_PE
-# define CONFIG_TCC_LIBPATHS "{B}/lib;{B}"
+# define CONFIG_TCC_LIBPATHS "{B}/lib"
# else
# define CONFIG_TCC_LIBPATHS \
- CONFIG_SYSROOT "/usr/" CONFIG_LDDIR \
- ":" CONFIG_SYSROOT "/" CONFIG_LDDIR \
- ":" CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR
+ ALSO_MUADIR(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
+ ":" ALSO_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
+ ":" ALSO_MUADIR(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
# endif
#endif
@@ -217,25 +252,30 @@
# else
# define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
# endif
+# elif defined __DragonFly__
+# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
# elif defined __GNU__
# define CONFIG_TCC_ELFINTERP "/lib/ld.so"
-# elif defined TCC_ARM_HARDFLOAT
-# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-armhf.so.3"
-# elif defined TCC_ARM_EABI
-# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.3"
# elif defined(TCC_TARGET_X86_64)
# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
# elif defined(TCC_UCLIBC)
# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0"
# elif defined(TCC_TARGET_PE)
# define CONFIG_TCC_ELFINTERP "-"
-# else
+# elif !defined(TCC_ARM_EABI)
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
# endif
#endif
+/* var elf_interp dans *-gen.c */
+#ifdef CONFIG_TCC_ELFINTERP
+# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
+#else
+# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
+#endif
+
/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
-#define TCC_LIBGCC CONFIG_SYSROOT "/" CONFIG_LDDIR "/libgcc_s.so.1"
+#define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
/* -------------------------------------------- */
/* include the target specific definitions */
@@ -310,7 +350,7 @@ typedef union CValue {
long long ll;
unsigned long long ull;
struct CString *cstr;
- void *ptr;
+ addr_t ptr_offset;
int tab[LDOUBLE_SIZE/4];
} CValue;
@@ -324,11 +364,36 @@ typedef struct SValue {
struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
} SValue;
+struct Attribute {
+ unsigned
+ func_call : 3, /* calling convention (0..5), see below */
+ aligned : 5, /* alignement (0..16) */
+ packed : 1,
+ func_export : 1,
+ func_import : 1,
+ func_args : 5,
+ func_proto : 1,
+ mode : 4,
+ weak : 1,
+ visibility : 2,
+ fill : 8; // 8 bits left to fit well in union below
+};
+
+/* GNUC attribute definition */
+typedef struct AttributeDef {
+ struct Attribute a;
+ struct Section *section;
+ int alias_target; /* token */
+} AttributeDef;
+
/* symbol management */
typedef struct Sym {
int v; /* symbol token */
char *asm_label; /* associated asm label */
- long r; /* associated register */
+ union {
+ long r; /* associated register */
+ struct Attribute a;
+ };
union {
long c; /* associated number */
int *d; /* define token stream */
@@ -379,32 +444,6 @@ typedef struct DLLReference {
char name[1];
} DLLReference;
-/* GNUC attribute definition */
-typedef struct AttributeDef {
- unsigned
- func_call : 3, /* calling convention (0..5), see below */
- aligned : 5, /* alignement (0..16) */
- packed : 1,
- func_export : 1,
- func_import : 1,
- func_args : 5,
- mode : 4,
- weak : 1,
- fill : 11;
- struct Section *section;
- int alias_target; /* token */
-} AttributeDef;
-
-/* gr: wrappers for casting sym->r for other purposes */
-#define FUNC_CALL(r) (((AttributeDef*)&(r))->func_call)
-#define FUNC_EXPORT(r) (((AttributeDef*)&(r))->func_export)
-#define FUNC_IMPORT(r) (((AttributeDef*)&(r))->func_import)
-#define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
-#define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
-#define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
-#define ATTR_MODE(r) (((AttributeDef*)&(r))->mode)
-#define INT_ATTR(ad) (*(int*)(ad))
-
/* -------------------------------------------------- */
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
@@ -519,6 +558,7 @@ typedef struct ASMOperand {
struct sym_attr {
unsigned long got_offset;
+ unsigned long plt_offset;
#ifdef TCC_TARGET_ARM
unsigned char plt_thumb_stub:1;
#endif
@@ -561,6 +601,9 @@ struct TCCState {
/* compile with built-in memory and bounds checker */
int do_bounds_check;
#endif
+#ifdef TCC_TARGET_ARM
+ enum float_abi float_abi; /* float ABI of the generated code*/
+#endif
addr_t text_addr; /* address of text section */
int has_text_addr;
@@ -665,18 +708,13 @@ struct TCCState {
#endif
#ifdef TCC_IS_NATIVE
+ const char *runtime_main;
/* for tcc_relocate */
void *runtime_mem;
# ifdef HAVE_SELINUX
void *write_mem;
unsigned long mem_size;
# endif
-# if !defined TCC_TARGET_PE && (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM)
- /* write PLT and GOT here */
- char *runtime_plt_and_got;
- unsigned runtime_plt_and_got_offset;
-# define TCC_HAS_RUNTIME_PLTGOT
-# endif
#endif
/* used by main and tcc_parse_args only */
@@ -738,7 +776,7 @@ struct TCCState {
#define VT_BITFIELD 0x0040 /* bitfield modifier */
#define VT_CONSTANT 0x0800 /* const modifier */
#define VT_VOLATILE 0x1000 /* volatile modifier */
-#define VT_SIGNED 0x2000 /* signed type */
+#define VT_DEFSIGN 0x2000 /* signed type */
#define VT_VLA 0x00020000 /* VLA type (also has VT_PTR and VT_ARRAY) */
/* storage */
@@ -749,11 +787,19 @@ struct TCCState {
#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
#define VT_WEAK 0x00010000 /* weak symbol */
+#define VT_TLS 0x00040000 /* thread-local storage */
+#define VT_VIS_SHIFT 19 /* shift for symbol visibility, overlapping
+ bitfield values, because bitfields never
+ have linkage and hence never have
+ visibility. */
+#define VT_VIS_SIZE 2 /* We have four visibilities. */
+#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT)
+
+#define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */
-#define VT_STRUCT_SHIFT 18 /* shift for bitfield shift values (max: 32 - 2*6) */
/* type mask (except storage) */
-#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK)
+#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK | VT_VIS_MASK)
#define VT_TYPE (~(VT_STORAGE))
/* token values */
@@ -774,35 +820,39 @@ struct TCCState {
#define TOK_LAND 0xa0
#define TOK_LOR 0xa1
-
#define TOK_DEC 0xa2
#define TOK_MID 0xa3 /* inc/dec, to void constant */
#define TOK_INC 0xa4
#define TOK_UDIV 0xb0 /* unsigned division */
#define TOK_UMOD 0xb1 /* unsigned modulo */
#define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
-#define TOK_CINT 0xb3 /* number in tokc */
-#define TOK_CCHAR 0xb4 /* char constant in tokc */
-#define TOK_STR 0xb5 /* pointer to string in tokc */
-#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
-#define TOK_LCHAR 0xb7
-#define TOK_LSTR 0xb8
-#define TOK_CFLOAT 0xb9 /* float constant */
-#define TOK_LINENUM 0xba /* line number info */
-#define TOK_CDOUBLE 0xc0 /* double constant */
-#define TOK_CLDOUBLE 0xc1 /* long double constant */
+
+/* tokens that carry values (in additional token string space / tokc) --> */
+#define TOK_CCHAR 0xb3 /* char constant in tokc */
+#define TOK_LCHAR 0xb4
+#define TOK_CINT 0xb5 /* number in tokc */
+#define TOK_CUINT 0xb6 /* unsigned int constant */
+#define TOK_CLLONG 0xb7 /* long long constant */
+#define TOK_CULLONG 0xb8 /* unsigned long long constant */
+#define TOK_STR 0xb9 /* pointer to string in tokc */
+#define TOK_LSTR 0xba
+#define TOK_CFLOAT 0xbb /* float constant */
+#define TOK_CDOUBLE 0xbc /* double constant */
+#define TOK_CLDOUBLE 0xbd /* long double constant */
+#define TOK_PPNUM 0xbe /* preprocessor number */
+#define TOK_LINENUM 0xbf /* line number info */
+/* <-- */
+
+#define TOK_TWOSHARPS 0xc0 /* ## preprocessing token */
+#define TOK_PLCHLDR 0xc1 /* placeholder token as defined in C99 */
#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
#define TOK_ADDC1 0xc3 /* add with carry generation */
#define TOK_ADDC2 0xc4 /* add with carry use */
#define TOK_SUBC1 0xc5 /* add with carry generation */
#define TOK_SUBC2 0xc6 /* add with carry use */
-#define TOK_CUINT 0xc8 /* unsigned int constant */
-#define TOK_CLLONG 0xc9 /* long long constant */
-#define TOK_CULLONG 0xca /* unsigned long long constant */
#define TOK_ARROW 0xcb
#define TOK_DOTS 0xcc /* three dots */
#define TOK_SHR 0xcd /* unsigned shift right */
-#define TOK_PPNUM 0xce /* preprocessor number */
#define TOK_NOSUBST 0xcf /* means following token has already been pp'd */
#define TOK_SHL 0x01 /* shift left */
@@ -926,37 +976,6 @@ enum tcc_token {
#define TOK_UIDENT TOK_DEFINE
-#ifdef _WIN32
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#ifndef __GNUC__
-# define strtold (long double)strtod
-# define strtof (float)strtod
-# define strtoll _strtoi64
-# define strtoull _strtoui64
-#endif
-#else
-/* XXX: need to define this to use them in non ISOC99 context */
-extern float strtof (const char *__nptr, char **__endptr);
-extern long double strtold (const char *__nptr, char **__endptr);
-#endif
-
-#ifdef _WIN32
-#define IS_DIRSEP(c) (c == '/' || c == '\\')
-#define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
-#define PATHCMP stricmp
-#else
-#define IS_DIRSEP(c) (c == '/')
-#define IS_ABSPATH(p) IS_DIRSEP(p[0])
-#define PATHCMP strcmp
-#endif
-
-#ifdef TCC_TARGET_PE
-#define PATHSEP ';'
-#else
-#define PATHSEP ':'
-#endif
-
/* space exlcuding newline */
static inline int is_space(int ch)
{
@@ -1033,7 +1052,7 @@ PUB_FUNC char *tcc_strdup(const char *str);
#define strdup(s) use_tcc_strdup(s)
PUB_FUNC void tcc_memstats(void);
PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
-PUB_FUNC void tcc_error(const char *fmt, ...);
+PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
PUB_FUNC void tcc_warning(const char *fmt, ...);
/* other utilities */
@@ -1131,7 +1150,7 @@ ST_FUNC void preprocess_init(TCCState *s1);
ST_FUNC void preprocess_new(void);
ST_FUNC int tcc_preprocess(TCCState *s1);
ST_FUNC void skip(int c);
-ST_FUNC void expect(const char *msg);
+ST_FUNC NORETURN void expect(const char *msg);
/* ------------ tccgen.c ------------ */
@@ -1169,6 +1188,7 @@ ST_DATA int const_wanted; /* true if constant wanted */
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic */
ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA char *funcname;
@@ -1250,6 +1270,7 @@ ST_FUNC void put_stabd(int type, int other, int desc);
ST_FUNC void relocate_common_syms(void);
ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
ST_FUNC void relocate_section(TCCState *s1, Section *s);
+ST_FUNC void relocate_plt(TCCState *s1);
ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
@@ -1260,7 +1281,7 @@ ST_FUNC void build_got_entries(TCCState *s1);
ST_FUNC void tcc_add_runtime(TCCState *s1);
ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
-#ifdef TCC_IS_NATIVE
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
#endif
@@ -1281,7 +1302,7 @@ ST_FUNC void gsym_addr(int t, int a);
ST_FUNC void gsym(int t);
ST_FUNC void load(int r, SValue *sv);
ST_FUNC void store(int r, SValue *v);
-ST_FUNC int gfunc_sret(CType *vt, CType *ret, int *align);
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align);
ST_FUNC void gfunc_call(int nb_args);
ST_FUNC void gfunc_prolog(CType *func_type);
ST_FUNC void gfunc_epilog(void);
@@ -1326,7 +1347,10 @@ ST_FUNC void gen_opl(int op);
/* ------------ arm-gen.c ------------ */
#ifdef TCC_TARGET_ARM
-ST_FUNC void arm_init_types(void);
+#ifdef TCC_ARM_EABI
+ST_FUNC char *default_elfinterp(struct TCCState *s);
+#endif
+ST_FUNC void arm_init(struct TCCState *s);
ST_FUNC uint32_t encbranch(int pos, int addr, int fail);
ST_FUNC void gen_cvt_itof1(int t);
#endif
@@ -1368,6 +1392,10 @@ ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
#ifdef TCC_TARGET_X86_64
ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
#endif
+/* symbol properties stored in Elf32_Sym->st_other */
+# define ST_PE_EXPORT 0x10
+# define ST_PE_IMPORT 0x20
+# define ST_PE_STDCALL 0x40
#endif
/* ------------ tccrun.c ----------------- */