|
|
|
@@ -35,13 +35,11 @@
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <setjmp.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
#include <sys/timeb.h>
|
|
|
|
|
#define CONFIG_TCC_STATIC
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef WIN32
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
@@ -52,9 +50,7 @@
|
|
|
|
|
|
|
|
|
|
#include "elf.h"
|
|
|
|
|
#include "stab.h"
|
|
|
|
|
#ifndef CONFIG_TCC_STATIC
|
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef O_BINARY
|
|
|
|
|
#define O_BINARY 0
|
|
|
|
|
#endif
|
|
|
|
@@ -218,6 +214,7 @@ typedef struct AttributeDef {
|
|
|
|
|
int packed;
|
|
|
|
|
Section *section;
|
|
|
|
|
unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
|
|
|
|
|
unsigned char dllexport;
|
|
|
|
|
} AttributeDef;
|
|
|
|
|
|
|
|
|
|
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
|
|
|
@@ -719,6 +716,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|
|
|
|
|
|
|
|
|
static char *pstrcpy(char *buf, int buf_size, const char *s);
|
|
|
|
|
static char *pstrcat(char *buf, int buf_size, const char *s);
|
|
|
|
|
static const char *tcc_basename(const char *name);
|
|
|
|
|
|
|
|
|
|
static void next(void);
|
|
|
|
|
static void next_nomacro(void);
|
|
|
|
@@ -809,6 +807,13 @@ static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
|
|
|
|
|
/* tcccoff.c */
|
|
|
|
|
int tcc_output_coff(TCCState *s1, FILE *f);
|
|
|
|
|
|
|
|
|
|
/* tccpe.c */
|
|
|
|
|
void *resolve_sym(TCCState *s1, const char *sym, int type);
|
|
|
|
|
int pe_load_def_file(struct TCCState *s1, FILE *fp);
|
|
|
|
|
void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
|
|
|
|
|
unsigned long pe_add_runtime(struct TCCState *s1);
|
|
|
|
|
int tcc_output_pe(struct TCCState *s1, const char *filename);
|
|
|
|
|
|
|
|
|
|
/* tccasm.c */
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_TCC_ASM
|
|
|
|
@@ -902,7 +907,7 @@ static TCCSyms tcc_syms[] = {
|
|
|
|
|
{ NULL, NULL },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void *dlsym(void *handle, const char *symbol)
|
|
|
|
|
void *resolve_sym(TCCState *s1, const char *symbol, int type)
|
|
|
|
|
{
|
|
|
|
|
TCCSyms *p;
|
|
|
|
|
p = tcc_syms;
|
|
|
|
@@ -914,6 +919,15 @@ void *dlsym(void *handle, const char *symbol)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#elif !defined(WIN32)
|
|
|
|
|
|
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
|
|
|
|
|
void *resolve_sym(TCCState *s1, const char *sym, int type)
|
|
|
|
|
{
|
|
|
|
|
return dlsym(RTLD_DEFAULT, sym);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/********************************************************/
|
|
|
|
@@ -6290,6 +6304,9 @@ static void parse_attribute(AttributeDef *ad)
|
|
|
|
|
skip(')');
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
case TOK_DLLEXPORT:
|
|
|
|
|
ad->dllexport = 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (tcc_state->warn_unsupported)
|
|
|
|
|
warning("'%s' attribute ignored", get_tok_str(t, NULL));
|
|
|
|
@@ -9195,6 +9212,10 @@ static void asm_global_instr(void)
|
|
|
|
|
#include "tcccoff.c"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
#include "tccpe.c"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* print the position in the source file of PC value 'pc' by reading
|
|
|
|
|
the stabs debug information */
|
|
|
|
|
static void rt_printline(unsigned long wanted_pc)
|
|
|
|
@@ -9442,7 +9463,11 @@ int tcc_relocate(TCCState *s1)
|
|
|
|
|
|
|
|
|
|
s1->nb_errors = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
pe_add_runtime(s1);
|
|
|
|
|
#else
|
|
|
|
|
tcc_add_runtime(s1);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
relocate_common_syms();
|
|
|
|
|
|
|
|
|
@@ -9588,9 +9613,17 @@ TCCState *tcc_new(void)
|
|
|
|
|
tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
|
|
|
|
|
|
|
|
|
|
/* default library paths */
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
{
|
|
|
|
|
char buf[1024];
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
|
|
|
|
|
tcc_add_library_path(s, buf);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
tcc_add_library_path(s, "/usr/local/lib");
|
|
|
|
|
tcc_add_library_path(s, "/usr/lib");
|
|
|
|
|
tcc_add_library_path(s, "/lib");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* no section zero */
|
|
|
|
|
dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
|
|
|
|
@@ -9727,6 +9760,11 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|
|
|
|
/* non preprocessed assembler */
|
|
|
|
|
ret = tcc_assemble(s1, 0);
|
|
|
|
|
} else
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
if (!strcmp(ext, "def")) {
|
|
|
|
|
ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
|
|
|
|
|
} else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
fd = file->fd;
|
|
|
|
@@ -9749,12 +9787,16 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|
|
|
|
ret = tcc_load_object_file(s1, fd, 0);
|
|
|
|
|
} else if (ehdr.e_type == ET_DYN) {
|
|
|
|
|
if (s1->output_type == TCC_OUTPUT_MEMORY) {
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
ret = -1;
|
|
|
|
|
#else
|
|
|
|
|
void *h;
|
|
|
|
|
h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
|
|
|
|
|
if (h)
|
|
|
|
|
ret = 0;
|
|
|
|
|
else
|
|
|
|
|
ret = -1;
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
ret = tcc_load_dll(s1, fd, filename,
|
|
|
|
|
(flags & AFF_REFERENCED_DLL) != 0);
|
|
|
|
@@ -9830,7 +9872,11 @@ int tcc_add_library(TCCState *s, const char *libraryname)
|
|
|
|
|
|
|
|
|
|
/* first we look for the dynamic library if not static linking */
|
|
|
|
|
if (!s->static_link) {
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s.def", libraryname);
|
|
|
|
|
#else
|
|
|
|
|
snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
|
|
|
|
|
#endif
|
|
|
|
|
if (tcc_add_dll(s, buf, 0) == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@@ -9855,17 +9901,23 @@ int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
|
|
|
|
|
|
|
|
|
|
int tcc_set_output_type(TCCState *s, int output_type)
|
|
|
|
|
{
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
|
|
s->output_type = output_type;
|
|
|
|
|
|
|
|
|
|
if (!s->nostdinc) {
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
|
|
/* default include paths */
|
|
|
|
|
/* XXX: reverse order needed if -isystem support */
|
|
|
|
|
#ifndef TCC_TARGET_PE
|
|
|
|
|
tcc_add_sysinclude_path(s, "/usr/local/include");
|
|
|
|
|
tcc_add_sysinclude_path(s, "/usr/include");
|
|
|
|
|
#endif
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
|
|
|
|
|
tcc_add_sysinclude_path(s, buf);
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
|
|
|
|
|
tcc_add_sysinclude_path(s, buf);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if bound checking, then add corresponding sections */
|
|
|
|
@@ -9898,12 +9950,14 @@ int tcc_set_output_type(TCCState *s, int output_type)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* add libc crt1/crti objects */
|
|
|
|
|
#ifndef TCC_TARGET_PE
|
|
|
|
|
if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
|
|
|
|
|
!s->nostdlib) {
|
|
|
|
|
if (output_type != TCC_OUTPUT_DLL)
|
|
|
|
|
tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
|
|
|
|
|
tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -10013,7 +10067,7 @@ static int64_t getclock_us(void)
|
|
|
|
|
|
|
|
|
|
void help(void)
|
|
|
|
|
{
|
|
|
|
|
printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2004 Fabrice Bellard\n"
|
|
|
|
|
printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2005 Fabrice Bellard\n"
|
|
|
|
|
"usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
|
|
|
|
|
" [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
|
|
|
|
|
" [infile1 infile2...] [-run infile args...]\n"
|
|
|
|
@@ -10370,6 +10424,22 @@ int main(int argc, char **argv)
|
|
|
|
|
char objfilename[1024];
|
|
|
|
|
int64_t start_time = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
/* on win32, we suppose the lib and includes are at the location
|
|
|
|
|
of 'tcc.exe' */
|
|
|
|
|
{
|
|
|
|
|
static char path[1024];
|
|
|
|
|
|
|
|
|
|
GetModuleFileNameA(NULL, path, sizeof path);
|
|
|
|
|
p = d = strlwr(path);
|
|
|
|
|
while (*d)
|
|
|
|
|
if (*d++ == '\\')
|
|
|
|
|
(p = d)[-1] = '/';
|
|
|
|
|
*p = '\0';
|
|
|
|
|
tcc_lib_path = path;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
s = tcc_new();
|
|
|
|
|
output_type = TCC_OUTPUT_EXE;
|
|
|
|
|
outfile = NULL;
|
|
|
|
@@ -10461,11 +10531,17 @@ int main(int argc, char **argv)
|
|
|
|
|
total_bytes / total_time / 1000000.0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s->output_type != TCC_OUTPUT_MEMORY) {
|
|
|
|
|
if (s->output_type == TCC_OUTPUT_MEMORY) {
|
|
|
|
|
ret = tcc_run(s, argc - optind, argv + optind);
|
|
|
|
|
} else
|
|
|
|
|
#ifdef TCC_TARGET_PE
|
|
|
|
|
if (s->output_type != TCC_OUTPUT_OBJ) {
|
|
|
|
|
ret = tcc_output_pe(s, outfile);
|
|
|
|
|
} else
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
tcc_output_file(s, outfile);
|
|
|
|
|
ret = 0;
|
|
|
|
|
} else {
|
|
|
|
|
ret = tcc_run(s, argc - optind, argv + optind);
|
|
|
|
|
}
|
|
|
|
|
the_end:
|
|
|
|
|
/* XXX: cannot do it with bound checking because of the malloc hooks */
|
|
|
|
|