/* * TCC - Tiny C Compiler * * Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TCC_H#define _TCC_H #define _GNU_SOURCE#define _DARWIN_C_SOURCE#include "config.h" #include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <math.h>#include <fcntl.h>#include <setjmp.h>#include <time.h> #ifndef _WIN32# define WIN32_LEAN_AND_MEAN 1# include <unistd.h># include <sys/time.h># ifndef CONFIG_TCC_STATIC# include <dlfcn.h># endif/* 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 WIN32_LEAN_AND_MEAN# include <windows.h># include <io.h> /* open, close etc. */# include <direct.h> /* getcwd */# ifdef __GNUC__# include <stdint.h># endif# define inline __inline# 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# endif# define inp next_inp /* inp is an intrinsic on msvc/mingw */# ifdef _MSC_VER# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data# pragma warning (disable : 4996) // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name# pragma warning (disable : 4018) // signed/unsigned mismatch# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned# define ssize_t intptr_t# ifdef _X86_# define __i386__ 1# endif# ifdef _AMD64_# define __x86_64__ 1# endif# endif# undef CONFIG_TCC_STATIC#endif #ifndef O_BINARY# define O_BINARY 0#endif #ifndef offsetof#define offsetof(type, field) ((size_t) &((type *)0)->field)#endif #ifndef countof#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))#endif #ifdef _MSC_VER# define NORETURN __declspec(noreturn)# define ALIGNED(x) __declspec(align(x))# define PRINTF_LIKE(x,y)#else# define NORETURN __attribute__((noreturn))# define ALIGNED(x) __attribute__((aligned(x)))# define PRINTF_LIKE(x,y) __attribute__ ((format (printf, (x), (y))))#endif /* gnu headers use to #define __attribute__ to empty for non-gcc compilers */#ifdef __TINYC__# undef __attribute__#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# define PATHSEP ";"#else# define IS_DIRSEP(c) (c == '/')# define IS_ABSPATH(p) IS_DIRSEP(p[0])# define PATHCMP strcmp# define PATHSEP ":"#endif /* -------------------------------------------- */ /* parser debug *//* #define PARSE_DEBUG *//* preprocessor debug *//* #define PP_DEBUG *//* include file debug *//* #define INC_DEBUG *//* memory leak debug (only for single threaded usage) *//* #define MEM_DEBUG *//* assembler debug *//* #define ASM_DEBUG */ /* target selection *//* #define TCC_TARGET_I386 *//* i386 code generator *//* #define TCC_TARGET_X86_64 *//* x86-64 code generator *//* #define TCC_TARGET_ARM *//* ARMv4 code generator *//* #define TCC_TARGET_ARM64 *//* ARMv8 code generator *//* #define TCC_TARGET_C67 *//* TMS320C67xx code generator *//* #define TCC_TARGET_RISCV64 *//* risc-v code generator */ /* default target is I386 */#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_RISCV64)# if defined __x86_64__# define TCC_TARGET_X86_64# elif defined __arm__# define TCC_TARGET_ARM# define TCC_ARM_EABI# define TCC_ARM_VFP# define TCC_ARM_HARDFLOAT# elif defined __aarch64__# define TCC_TARGET_ARM64# elif defined __riscv# define TCC_TARGET_RISCV64# else# define TCC_TARGET_I386# endif# ifdef _WIN32# define TCC_TARGET_PE 1# endif#endif /* only native compiler supports -run */#if defined _WIN32 == defined TCC_TARGET_PE# if defined __i386__ && defined TCC_TARGET_I386# define TCC_IS_NATIVE# elif defined __x86_64__ && defined TCC_TARGET_X86_64# define TCC_IS_NATIVE# elif defined __arm__ && defined TCC_TARGET_ARM# define TCC_IS_NATIVE# elif defined __aarch64__ && defined TCC_TARGET_ARM64# define TCC_IS_NATIVE# elif defined __riscv && defined __LP64__ && defined TCC_TARGET_RISCV64# define TCC_IS_NATIVE# endif#endif #if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT# define CONFIG_TCC_BACKTRACE# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \ defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \ defined TCC_TARGET_RISCV64) \ && !defined TCC_UCLIBC && !defined TCC_MUSL# define CONFIG_TCC_BCHECK /* enable bound checking code */# endif#endif #if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO# define ELF_OBJ_ONLY /* create elf .o but native executables */#endif /* ------------ path configuration ------------ */ #ifndef CONFIG_SYSROOT# define CONFIG_SYSROOT ""#endif#ifndef CONFIG_TCCDIR# define CONFIG_TCCDIR "/usr/local/lib/tcc"#endif#ifndef CONFIG_LDDIR# define CONFIG_LDDIR "lib"#endif#ifdef CONFIG_TRIPLET# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s#else# define USE_TRIPLET(s) s# define ALSO_TRIPLET(s) s#endif /* path to find crt1.o, crti.o and crtn.o */#ifndef CONFIG_TCC_CRTPREFIX# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)#endif #ifndef CONFIG_USR_INCLUDE# define CONFIG_USR_INCLUDE "/usr/include"#endif /* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */ /* system include paths */#ifndef CONFIG_TCC_SYSINCLUDEPATHS# if defined TCC_TARGET_PE || defined _WIN32# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"# else# define CONFIG_TCC_SYSINCLUDEPATHS \ "{B}/include" \ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \ ":" ALSO_TRIPLET(CONFIG_SYSROOT CONFIG_USR_INCLUDE)# endif#endif /* library search paths */#ifndef CONFIG_TCC_LIBPATHS# ifdef TCC_TARGET_PE# define CONFIG_TCC_LIBPATHS "{B}/lib"# else# define CONFIG_TCC_LIBPATHS \ ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)# endif#endif /* name of ELF interpreter */#ifndef CONFIG_TCC_ELFINTERP# if defined __FreeBSD__# define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"# elif defined __FreeBSD_kernel__# if defined(TCC_TARGET_X86_64)# define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"# 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 __NetBSD__# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"# elif defined __GNU__# define CONFIG_TCC_ELFINTERP "/lib/ld.so"# elif defined(TCC_TARGET_PE)# define CONFIG_TCC_ELFINTERP "-"# elif defined(TCC_UCLIBC)# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */# elif defined TCC_TARGET_ARM64# if defined(TCC_MUSL)# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"# else# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"# endif# elif defined(TCC_TARGET_X86_64)# if defined(TCC_MUSL)# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"# else# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"# endif# elif defined(TCC_TARGET_RISCV64)# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"# elif !defined(TCC_ARM_EABI)# if defined(TCC_MUSL)# if defined(TCC_TARGET_I386)# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-i386.so.1"# else# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"# endif# else# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"# endif# 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 /* (target specific) libtcc1.a */#ifndef TCC_LIBTCC1# define TCC_LIBTCC1 "libtcc1.a"#endif /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"#endif /* -------------------------------------------- */ #include "libtcc.h"#include "elf.h"#include "stab.h" /* -------------------------------------------- */ #ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */# define PUB_FUNC#endif #ifndef ONE_SOURCE# define ONE_SOURCE 1#endif /* support using libtcc from threads */#define CONFIG_TCC_SEMLOCK #if ONE_SOURCE#define ST_INLN static inline#define ST_FUNC static#define ST_DATA static#else#define ST_INLN#define ST_FUNC#define ST_DATA extern#endif #ifdef TCC_PROFILE /* profile all functions */# define static#endif /* -------------------------------------------- *//* include the target specific definitions */ #define TARGET_DEFS_ONLY#ifdef TCC_TARGET_I386# include "i386-gen.c"# include "i386-link.c"#elif defined TCC_TARGET_X86_64# include "x86_64-gen.c"# include "x86_64-link.c"#elif defined TCC_TARGET_ARM# include "arm-gen.c"# include "arm-link.c"# include "arm-asm.c"#elif defined TCC_TARGET_ARM64# include "arm64-gen.c"# include "arm64-link.c"# include "arm-asm.c"#elif defined TCC_TARGET_C67# define TCC_TARGET_COFF# include "coff.h"# include "c67-gen.c"# include "c67-link.c"#elif defined(TCC_TARGET_RISCV64)# include "riscv64-gen.c"# include "riscv64-link.c"# include "riscv64-asm.c"#else#error unknown target#endif#undef TARGET_DEFS_ONLY /* -------------------------------------------- */ #if PTR_SIZE == 8# define ELFCLASSW ELFCLASS64# define ElfW(type) Elf##64##_##type# define ELFW(type) ELF##64##_##type# define ElfW_Rel ElfW(Rela)# define SHT_RELX SHT_RELA# define REL_SECTION_FMT ".rela%s"#else# define ELFCLASSW ELFCLASS32# define ElfW(type) Elf##32##_##type# define ELFW(type) ELF##32##_##type# define ElfW_Rel ElfW(Rel)# define SHT_RELX SHT_REL# define REL_SECTION_FMT ".rel%s"#endif/* target address type */#define addr_t ElfW(Addr)#define ElfSym ElfW(Sym) #if PTR_SIZE == 8 && !defined TCC_TARGET_PE# define LONG_SIZE 8#else# define LONG_SIZE 4#endif /* -------------------------------------------- */ #define INCLUDE_STACK_SIZE 32#define IFDEF_STACK_SIZE 64#define VSTACK_SIZE 256#define STRING_MAX_SIZE 1024#define TOKSTR_MAX_SIZE 256#define PACK_STACK_SIZE 8 #define TOK_HASH_SIZE 16384 /* must be a power of two */#define TOK_ALLOC_INCR 512 /* must be a power of two */#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ /* token symbol management */typedef struct TokenSym { struct TokenSym *hash_next; struct Sym *sym_define; /* direct pointer to define */ struct Sym *sym_label; /* direct pointer to label */ struct Sym *sym_struct; /* direct pointer to structure */ struct Sym *sym_identifier; /* direct pointer to identifier */ int tok; /* token number */ int len; char str[1];} TokenSym; #ifdef TCC_TARGET_PEtypedef unsigned short nwchar_t;#elsetypedef int nwchar_t;#endif typedef struct CString { int size; /* size in bytes */ void *data; /* either 'char *' or 'nwchar_t *' */ int size_allocated;} CString; /* type definition */typedef struct CType { int t; struct Sym *ref;} CType; /* constant value */typedef union CValue { long double ld; double d; float f; uint64_t i; struct { const void *data; int size; } str; int tab[LDOUBLE_SIZE/4];} CValue; /* value on stack */typedef struct SValue { CType type; /* type */ unsigned short r; /* register + flags */ unsigned short r2; /* second register, used for 'long long' type. If not used, set to VT_CONST */ union { struct { int jtrue, jfalse; }; /* forward jmps */ CValue c; /* constant, if VT_CONST */ }; union { struct { unsigned short cmp_op, cmp_r; }; /* VT_CMP operation */ struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST), or if */ }; /* result of unary() for an identifier. */ } SValue; /* symbol attributes */struct SymAttr { unsigned short aligned : 5, /* alignment as log2+1 (0 == unspecified) */ packed : 1, weak : 1, visibility : 2, dllexport : 1, nodecorate : 1, dllimport : 1, addrtaken : 1, xxxx : 3; /* not used */}; /* function attributes or temporary attributes for parsing */struct FuncAttr { unsignedLines 1–500 of 1821. Load more
/* * TCC - Tiny C Compiler * * Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _TCC_H #define _TCC_H #define _GNU_SOURCE #define _DARWIN_C_SOURCE #include "config.h" #include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <math.h> #include <fcntl.h> #include <setjmp.h> #include <time.h> #ifndef _WIN32 # define WIN32_LEAN_AND_MEAN 1 # include <unistd.h> # include <sys/time.h> # ifndef CONFIG_TCC_STATIC # include <dlfcn.h> # endif /* 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 WIN32_LEAN_AND_MEAN # include <windows.h> # include <io.h> /* open, close etc. */ # include <direct.h> /* getcwd */ # ifdef __GNUC__ # include <stdint.h> # endif # define inline __inline # 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 # endif # define inp next_inp /* inp is an intrinsic on msvc/mingw */ # ifdef _MSC_VER # pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data # pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data # pragma warning (disable : 4996) // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name # pragma warning (disable : 4018) // signed/unsigned mismatch # pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned # define ssize_t intptr_t # ifdef _X86_ # define __i386__ 1 # endif # ifdef _AMD64_ # define __x86_64__ 1 # endif # endif # undef CONFIG_TCC_STATIC #endif #ifndef O_BINARY # define O_BINARY 0 #endif #ifndef offsetof #define offsetof(type, field) ((size_t) &((type *)0)->field) #endif #ifndef countof #define countof(tab) (sizeof(tab) / sizeof((tab)[0])) #endif #ifdef _MSC_VER # define NORETURN __declspec(noreturn) # define ALIGNED(x) __declspec(align(x)) # define PRINTF_LIKE(x,y) #else # define NORETURN __attribute__((noreturn)) # define ALIGNED(x) __attribute__((aligned(x))) # define PRINTF_LIKE(x,y) __attribute__ ((format (printf, (x), (y)))) #endif /* gnu headers use to #define __attribute__ to empty for non-gcc compilers */ #ifdef __TINYC__ # undef __attribute__ #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 # define PATHSEP ";" #else # define IS_DIRSEP(c) (c == '/') # define IS_ABSPATH(p) IS_DIRSEP(p[0]) # define PATHCMP strcmp # define PATHSEP ":" #endif /* -------------------------------------------- */ /* parser debug */ /* #define PARSE_DEBUG */ /* preprocessor debug */ /* #define PP_DEBUG */ /* include file debug */ /* #define INC_DEBUG */ /* memory leak debug (only for single threaded usage) */ /* #define MEM_DEBUG */ /* assembler debug */ /* #define ASM_DEBUG */ /* target selection */ /* #define TCC_TARGET_I386 *//* i386 code generator */ /* #define TCC_TARGET_X86_64 *//* x86-64 code generator */ /* #define TCC_TARGET_ARM *//* ARMv4 code generator */ /* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */ /* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */ /* #define TCC_TARGET_RISCV64 *//* risc-v code generator */ /* default target is I386 */ #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_RISCV64) # if defined __x86_64__ # define TCC_TARGET_X86_64 # elif defined __arm__ # define TCC_TARGET_ARM # define TCC_ARM_EABI # define TCC_ARM_VFP # define TCC_ARM_HARDFLOAT # elif defined __aarch64__ # define TCC_TARGET_ARM64 # elif defined __riscv # define TCC_TARGET_RISCV64 # else # define TCC_TARGET_I386 # endif # ifdef _WIN32 # define TCC_TARGET_PE 1 # endif #endif /* only native compiler supports -run */ #if defined _WIN32 == defined TCC_TARGET_PE # if defined __i386__ && defined TCC_TARGET_I386 # define TCC_IS_NATIVE # elif defined __x86_64__ && defined TCC_TARGET_X86_64 # define TCC_IS_NATIVE # elif defined __arm__ && defined TCC_TARGET_ARM # define TCC_IS_NATIVE # elif defined __aarch64__ && defined TCC_TARGET_ARM64 # define TCC_IS_NATIVE # elif defined __riscv && defined __LP64__ && defined TCC_TARGET_RISCV64 # define TCC_IS_NATIVE # endif #endif #if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT # define CONFIG_TCC_BACKTRACE # if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || \ defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || \ defined TCC_TARGET_RISCV64) \ && !defined TCC_UCLIBC && !defined TCC_MUSL # define CONFIG_TCC_BCHECK /* enable bound checking code */ # endif #endif #if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO # define ELF_OBJ_ONLY /* create elf .o but native executables */ #endif /* ------------ path configuration ------------ */ #ifndef CONFIG_SYSROOT # define CONFIG_SYSROOT "" #endif #ifndef CONFIG_TCCDIR # define CONFIG_TCCDIR "/usr/local/lib/tcc" #endif #ifndef CONFIG_LDDIR # define CONFIG_LDDIR "lib" #endif #ifdef CONFIG_TRIPLET # define USE_TRIPLET(s) s "/" CONFIG_TRIPLET # define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s #else # define USE_TRIPLET(s) s # define ALSO_TRIPLET(s) s #endif /* path to find crt1.o, crti.o and crtn.o */ #ifndef CONFIG_TCC_CRTPREFIX # define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) #endif #ifndef CONFIG_USR_INCLUDE # define CONFIG_USR_INCLUDE "/usr/include" #endif /* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */ /* system include paths */ #ifndef CONFIG_TCC_SYSINCLUDEPATHS # if defined TCC_TARGET_PE || defined _WIN32 # define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi" # else # define CONFIG_TCC_SYSINCLUDEPATHS \ "{B}/include" \ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \ ":" ALSO_TRIPLET(CONFIG_SYSROOT CONFIG_USR_INCLUDE) # endif #endif /* library search paths */ #ifndef CONFIG_TCC_LIBPATHS # ifdef TCC_TARGET_PE # define CONFIG_TCC_LIBPATHS "{B}/lib" # else # define CONFIG_TCC_LIBPATHS \ ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR) # endif #endif /* name of ELF interpreter */ #ifndef CONFIG_TCC_ELFINTERP # if defined __FreeBSD__ # define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1" # elif defined __FreeBSD_kernel__ # if defined(TCC_TARGET_X86_64) # define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1" # 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 __NetBSD__ # define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so" # elif defined __GNU__ # define CONFIG_TCC_ELFINTERP "/lib/ld.so" # elif defined(TCC_TARGET_PE) # define CONFIG_TCC_ELFINTERP "-" # elif defined(TCC_UCLIBC) # define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */ # elif defined TCC_TARGET_ARM64 # if defined(TCC_MUSL) # define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1" # else # define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1" # endif # elif defined(TCC_TARGET_X86_64) # if defined(TCC_MUSL) # define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1" # else # define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2" # endif # elif defined(TCC_TARGET_RISCV64) # define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1" # elif !defined(TCC_ARM_EABI) # if defined(TCC_MUSL) # if defined(TCC_TARGET_I386) # define CONFIG_TCC_ELFINTERP "/lib/ld-musl-i386.so.1" # else # define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1" # endif # else # define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2" # endif # 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 /* (target specific) libtcc1.a */ #ifndef TCC_LIBTCC1 # define TCC_LIBTCC1 "libtcc1.a" #endif /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */ #if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC #define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" #endif /* -------------------------------------------- */ #include "libtcc.h" #include "elf.h" #include "stab.h" /* -------------------------------------------- */ #ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */ # define PUB_FUNC #endif #ifndef ONE_SOURCE # define ONE_SOURCE 1 #endif /* support using libtcc from threads */ #define CONFIG_TCC_SEMLOCK #if ONE_SOURCE #define ST_INLN static inline #define ST_FUNC static #define ST_DATA static #else #define ST_INLN #define ST_FUNC #define ST_DATA extern #endif #ifdef TCC_PROFILE /* profile all functions */ # define static #endif /* -------------------------------------------- */ /* include the target specific definitions */ #define TARGET_DEFS_ONLY #ifdef TCC_TARGET_I386 # include "i386-gen.c" # include "i386-link.c" #elif defined TCC_TARGET_X86_64 # include "x86_64-gen.c" # include "x86_64-link.c" #elif defined TCC_TARGET_ARM # include "arm-gen.c" # include "arm-link.c" # include "arm-asm.c" #elif defined TCC_TARGET_ARM64 # include "arm64-gen.c" # include "arm64-link.c" # include "arm-asm.c" #elif defined TCC_TARGET_C67 # define TCC_TARGET_COFF # include "coff.h" # include "c67-gen.c" # include "c67-link.c" #elif defined(TCC_TARGET_RISCV64) # include "riscv64-gen.c" # include "riscv64-link.c" # include "riscv64-asm.c" #else #error unknown target #endif #undef TARGET_DEFS_ONLY /* -------------------------------------------- */ #if PTR_SIZE == 8 # define ELFCLASSW ELFCLASS64 # define ElfW(type) Elf##64##_##type # define ELFW(type) ELF##64##_##type # define ElfW_Rel ElfW(Rela) # define SHT_RELX SHT_RELA # define REL_SECTION_FMT ".rela%s" #else # define ELFCLASSW ELFCLASS32 # define ElfW(type) Elf##32##_##type # define ELFW(type) ELF##32##_##type # define ElfW_Rel ElfW(Rel) # define SHT_RELX SHT_REL # define REL_SECTION_FMT ".rel%s" #endif /* target address type */ #define addr_t ElfW(Addr) #define ElfSym ElfW(Sym) #if PTR_SIZE == 8 && !defined TCC_TARGET_PE # define LONG_SIZE 8 #else # define LONG_SIZE 4 #endif /* -------------------------------------------- */ #define INCLUDE_STACK_SIZE 32 #define IFDEF_STACK_SIZE 64 #define VSTACK_SIZE 256 #define STRING_MAX_SIZE 1024 #define TOKSTR_MAX_SIZE 256 #define PACK_STACK_SIZE 8 #define TOK_HASH_SIZE 16384 /* must be a power of two */ #define TOK_ALLOC_INCR 512 /* must be a power of two */ #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ /* token symbol management */ typedef struct TokenSym { struct TokenSym *hash_next; struct Sym *sym_define; /* direct pointer to define */ struct Sym *sym_label; /* direct pointer to label */ struct Sym *sym_struct; /* direct pointer to structure */ struct Sym *sym_identifier; /* direct pointer to identifier */ int tok; /* token number */ int len; char str[1]; } TokenSym; #ifdef TCC_TARGET_PE typedef unsigned short nwchar_t; #else typedef int nwchar_t; #endif typedef struct CString { int size; /* size in bytes */ void *data; /* either 'char *' or 'nwchar_t *' */ int size_allocated; } CString; /* type definition */ typedef struct CType { int t; struct Sym *ref; } CType; /* constant value */ typedef union CValue { long double ld; double d; float f; uint64_t i; struct { const void *data; int size; } str; int tab[LDOUBLE_SIZE/4]; } CValue; /* value on stack */ typedef struct SValue { CType type; /* type */ unsigned short r; /* register + flags */ unsigned short r2; /* second register, used for 'long long' type. If not used, set to VT_CONST */ union { struct { int jtrue, jfalse; }; /* forward jmps */ CValue c; /* constant, if VT_CONST */ }; union { struct { unsigned short cmp_op, cmp_r; }; /* VT_CMP operation */ struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST), or if */ }; /* result of unary() for an identifier. */ } SValue; /* symbol attributes */ struct SymAttr { unsigned short aligned : 5, /* alignment as log2+1 (0 == unspecified) */ packed : 1, weak : 1, visibility : 2, dllexport : 1, nodecorate : 1, dllimport : 1, addrtaken : 1, xxxx : 3; /* not used */ }; /* function attributes or temporary attributes for parsing */ struct FuncAttr { unsigned